IIS/ASP.NET访问共享文件夹的可用方式

【截止2014-10-14】

网上搜索了很多篇文章,所提及的总共有两种方式:

1.Asp.Net模拟登陆;

例如:

实战ASP.NET访问共享文件夹(含详细操作步骤)

实现一个2008serve的IIS的虚拟目录(通过网络路径(UNC)的形式,共享在另外一个2008服务器上

2.调用Windows API 的 WNetAddConnection2 、WNetCancelConnection2函数;

例如:

ASP.NET网络映射驱动器无权限访问的解决方案
ASP.NET访问网络驱动器(映射磁盘)

共享访问在.NET中的编程实现

相对来说,第一种方式是最直接的,且改动较小的。但不足之处就是比较依赖共享所在服务器(如果切换共享服务器地址,那么本地的用户名和密码都要作调整。);

而第二种方式缺点(个人感觉),API函数的不稳定、链接数超出限制、内存泄露等不稳定的问题(如果有哪位朋友有解决方案,还请告知,谢谢)。

ps:折腾了两天,先用第一种方式吧。附上一个第二种方式的辅助类。

  1 #define CheckReturn
  2 using System;
  3 using System.Collections.Generic;
  4 using System.Text;
  5 using System.Runtime.InteropServices;
  6 
  7 
  8 /// <summary>
  9 /// 网络资源访问
 10 /// </summary>
 11 public class WNetConnectionHelper : IDisposable
 12 {
 13 
 14     /// <summary>
 15     /// 添加远程网络连接。
 16     /// </summary>
 17     /// <param name="lpNetResource">是一个包含网络访问资源的结构,在这里作为参数用来指定详细的网络连接信息</param>
 18     /// <param name="lpPassword">指出访问远程计算机的密码。在Windows 95/98/Me 系统中,该值必须设置为NULL或空字符串</param>
 19     /// <param name="lpUsername">指出访问远程计算机的用户名。在Windows 95/98/Me 系统中,该值必须设置为NULL或空字符串</param>
 20     /// <param name="dwFlags">指出连接选项,包含六种设置</param>
 21     /// <returns>如果方法执行成功返回“NO_ERROR”即“0”。如果执行失败返回System Error Code。</returns>
 22     [DllImport("Mpr.dll", EntryPoint = "WNetAddConnection2")]
 23     /*
 24     private static extern uint WNetAddConnection2(NetResource lpNetResource, [MarshalAs(UnmanagedType.LPStr)]string lpPassword, [MarshalAs(UnmanagedType.LPStr)]string lpUsername, uint dwFlags);
 25     */
 26     private static extern uint WNetAddConnection2(IntPtr lpNetResource, string lpPassword, string lpUsername, uint dwFlags);
 27 
 28     /// <summary>
 29     /// 释放存在的网络连接。
 30     /// </summary>
 31     /// <param name="lpName">指定本地驱动器或远程共享资源</param>
 32     /// <param name="dwFlags">表示断开连接方式。设置 0 或CONNECT_UPDATE_PROFILE。</param>
 33     /// <param name="fForce">如果当前正在使用远程资源,是否进行强制断开连接。如果设置FALSE,在有远程资源使用的情况下关闭连接操作将会失败。</param>
 34     /// <returns>如果方法执行成功返回“NO_ERROR”即“0”。如果执行失败返回System Error Code。</returns>
 35     [DllImport("Mpr.dll", EntryPoint = "WNetCancelConnection2")]
 36     private static extern uint WNetCancelConnection2([MarshalAs(UnmanagedType.LPStr)]string lpName, uint dwFlags, int fForce);
 37 
 38 
 39     /// <summary>
 40     /// 获取网络错误的扩展错误信息
 41     /// </summary>
 42     /// <param name="lpError">指定一个变量,用于装载网络错误代码。具体的代码由网络供应商决定</param>
 43     /// <param name="lpErrorBuf">指定一个字串缓冲区,用于装载网络错误的说明</param>
 44     /// <param name="nErrorBufSize">lpErrorBuf缓冲区包含的字符数量</param>
 45     /// <param name="lpNameBuf">用于装载网络供应商名字的字串缓冲区</param>
 46     /// <param name="nNameBufSize">lpNameBuf缓冲区的字符数量</param>
 47     /// <returns></returns>
 48     [DllImport("Mpr.dll", EntryPoint = "WNetGetLastError")]
 49     private static extern uint WNetGetLastError(ref uint lpError, [MarshalAs(UnmanagedType.LPStr)]ref string lpErrorBuf, long nErrorBufSize, [MarshalAs(UnmanagedType.LPStr)]ref  string lpNameBuf, uint nNameBufSize);
 50 
 51     [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
 52     public struct NetResource
 53     {
 54         /// <summary>
 55         /// 指定枚举范围。设置RESOURCE_CONNECTED,RESOURCE_GLOBALNET,RESOURCE_REMEMBERED三值之一。
 56         /// </summary>
 57         public int dwScope;
 58         /// <summary>
 59         /// 指定访问的资源类型。设置三个值之一。RESOURCETYPE_ANY表示所有资源;RESOURCETYPE_DISK表示磁盘资源;RESOURCETYPE_PRINT表示打印机。
 60         /// </summary>
 61         public int dwType;
 62         /// <summary>
 63         /// 指出资源显示类型。RESOURCEDISPLAYTYPE_DOMAIN;RESOURCEDISPLAYTYPE_SERVER;RESOURCEDISPLAYTYPE_SHARE;RESOURCEDISPLAYTYPE_GENERIC。
 64         /// </summary>
 65         public int dwDisplayType;
 66         /// <summary>
 67         /// 描述资源的使用方式。设置RESOURCEUSAGE_CONNECTABLE 或RESOURCEUSAGE_CONTAINER。
 68         /// </summary>
 69         public int dwUsage;
 70         /// <summary>
 71         /// 同dwScope关联,指定本地映射。
 72         /// </summary>
 73         //[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
 74         public string lpLocalName;
 75         /// <summary>
 76         /// 远程访问文件夹路径。
 77         /// </summary>
 78         //[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
 79         public string lpRemoteName;
 80         /// <summary>
 81         /// 描述。
 82         /// </summary>
 83         //[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
 84         public string lpComment;
 85         /// <summary>
 86         /// 资源提供者,可以设置为NULL。
 87         /// </summary>
 88         //[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
 89         public string lpProvider;
 90     }
 91 
 92 
 93     public enum RESOURCE_SCOPE
 94     {
 95         RESOURCE_CONNECTED = 1,
 96         RESOURCE_GLOBALNET = 2,
 97         RESOURCE_REMEMBERED = 3,
 98         RESOURCE_RECENT = 4,
 99         RESOURCE_CONTEXT = 5
100     }
101 
102     public enum RESOURCE_TYPE
103     {
104         RESOURCETYPE_ANY = 0,
105         RESOURCETYPE_DISK = 1,
106         RESOURCETYPE_PRINT = 2,
107         RESOURCETYPE_RESERVED = 8,
108     }
109 
110     public enum RESOURCE_USAGE
111     {
112         RESOURCEUSAGE_CONNECTABLE = 1,
113         RESOURCEUSAGE_CONTAINER = 2,
114         RESOURCEUSAGE_NOLOCALDEVICE = 4,
115         RESOURCEUSAGE_SIBLING = 8,
116         RESOURCEUSAGE_ATTACHED = 16,
117         RESOURCEUSAGE_ALL = (RESOURCEUSAGE_CONNECTABLE | RESOURCEUSAGE_CONTAINER | RESOURCEUSAGE_ATTACHED),
118     }
119 
120     public enum RESOURCE_DISPLAYTYPE
121     {
122         RESOURCEDISPLAYTYPE_GENERIC = 0,
123         RESOURCEDISPLAYTYPE_DOMAIN = 1,
124         RESOURCEDISPLAYTYPE_SERVER = 2,
125         RESOURCEDISPLAYTYPE_SHARE = 3,
126         RESOURCEDISPLAYTYPE_FILE = 4,
127         RESOURCEDISPLAYTYPE_GROUP = 5,
128         RESOURCEDISPLAYTYPE_NETWORK = 6,
129         RESOURCEDISPLAYTYPE_ROOT = 7,
130         RESOURCEDISPLAYTYPE_SHAREADMIN = 8,
131         RESOURCEDISPLAYTYPE_DIRECTORY = 9,
132         RESOURCEDISPLAYTYPE_TREE = 10,
133         RESOURCEDISPLAYTYPE_NDSCONTAINER = 11
134     }
135 
136 
137     /// <summary>
138     /// 添加远程网络连接。
139     /// </summary>
140     /// <param name="netResource">是一个包含网络访问资源的结构,在这里作为参数用来指定详细的网络连接信息</param>
141     /// <param name="username">指出访问远程计算机的用户名。在Windows 95/98/Me 系统中,该值必须设置为NULL或空字符串</param>
142     /// <param name="password">指出访问远程计算机的密码。在Windows 95/98/Me 系统中,该值必须设置为NULL或空字符串</param>
143     /// <returns>如果方法执行成功返回“NO_ERROR”即“0”。如果执行失败返回System Error Code。</returns>
144     public static uint WNetAddConnection(NetResource netResource, string username, string password)
145     {
146         IntPtr ptr_netResource = IntPtr.Zero;
147         try
148         {
149             //分配内存
150             ptr_netResource = System.Runtime.InteropServices.Marshal.AllocHGlobal(System.Runtime.InteropServices.Marshal.SizeOf(netResource));
151             System.Runtime.InteropServices.Marshal.StructureToPtr(netResource, ptr_netResource, false);
152 
153             uint result = WNetAddConnection2(ptr_netResource, password, username, 0);
154             return result;
155         }
156         finally
157         {
158             if (ptr_netResource != IntPtr.Zero)
159                 System.Runtime.InteropServices.Marshal.FreeCoTaskMem(ptr_netResource);
160         }
161         /*
162         uint result = WNetAddConnection2(netResource, password, username, 0);
163         return result;
164         */
165     }
166 
167     /// <summary>
168     /// 添加远程网络连接。
169     /// </summary>
170     /// <param name="username">指出访问远程计算机的用户名。在Windows 95/98/Me 系统中,该值必须设置为NULL或空字符串</param>
171     /// <param name="password">指出访问远程计算机的密码。在Windows 95/98/Me 系统中,该值必须设置为NULL或空字符串</param>
172     /// <param name="remoteName">远程访问文件夹路径。</param>
173     /// <param name="localName">同dwScope关联,指定本地映射。</param>
174     /// <returns>如果方法执行成功返回“NO_ERROR”即“0”。如果执行失败返回System Error Code。</returns>
175     public static uint WNetAddConnection(string username, string password, string remoteName, string localName)
176     {
177         NetResource netResource = new NetResource();
178         netResource.dwScope = 2;       //RESOURCE_GLOBALNET
179         netResource.dwType = 1;       //RESOURCETYPE_DISK
180         netResource.dwDisplayType = 3; //RESOURCEDISPLAYTYPE_SHARE
181         netResource.dwUsage = 1;       //RESOURCEUSAGE_CONNECTABLE
182         netResource.lpLocalName = localName;
183         netResource.lpRemoteName = remoteName.TrimEnd('/');
184         //netResource.lpRemoteName = lpComment;
185         //netResource.lpProvider = null;
186         uint result = WNetAddConnection(netResource, username, password);
187         return result;
188     }
189 
190     /// <summary>
191     /// 添加远程网络连接。
192     /// </summary>
193     /// <param name="name">指定本地驱动器或远程共享资源</param>
194     /// <param name="flags">表示断开连接方式。设置 0 或CONNECT_UPDATE_PROFILE。</param>
195     /// <param name="force">如果当前正在使用远程资源,是否进行强制断开连接。如果设置FALSE,在有远程资源使用的情况下关闭连接操作将会失败。</param>
196     /// <returns>如果方法执行成功返回“NO_ERROR”即“0”。如果执行失败返回System Error Code。</returns>
197     public static uint WNetCancelConnection(string name, uint flags, bool force)
198     {
199         uint nret = WNetCancelConnection2(name, flags, force ? 1 : 0);
200         return nret;
201     }
202 
203 
204     #region SelfUsing
205     bool connectSuccess = false;
206     string username, password, remoteName, localName;
207     private WNetConnectionHelper(string username, string password, string remoteName, string localName)
208     {
209         this.username = username;
210         this.password = password;
211         this.remoteName = remoteName;
212         this.localName = localName;
213         Close();
214         var code = WNetAddConnection(username, password, remoteName, localName);
215         connectSuccess = code == 0;
216 #if CheckReturn
217 
218         if (code != 0)
219         {
220             GetLastError();
221 
222             throw new InvalidOperationException("The method WNetAddConnection return " + code);
223         }
224 #endif
225     }
226 
227     private static void GetLastError()
228     {
229         uint lpError = 0;
230         string lpErrorBuf = null;
231         uint nErrorBufSize = 1024;
232         string lpNameBuf = null;
233         uint nNameBufSize = 1024;
234         var errCode = WNetGetLastError(ref lpError, ref lpErrorBuf, nErrorBufSize, ref lpNameBuf, nNameBufSize);
235     }
236 
237     public static WNetConnectionHelper New(string username, string password, string remoteName, string localName)
238     {
239         if (string.IsNullOrEmpty(remoteName))
240             throw new ArgumentException("remoteName");
241         return new WNetConnectionHelper(username, password, remoteName.TrimEnd('/'), localName);
242     }
243 
244 
245     #endregion
246 
247     #region IDisposable 成员
248 
249     public void Dispose()
250     {
251         if (!connectSuccess) return;
252         if (string.IsNullOrEmpty(remoteName)) return;
253         var code = Close();
254 #if CheckReturn
255         if (code != 0)
256         {
257             GetLastError();
258             throw new InvalidOperationException("The method WNetCancelConnection return " + code);
259 
260         }
261 #endif
262     }
263 
264     private uint Close()
265     {
266 
267         return WNetCancelConnection(remoteName, 1, true);
268     }
269 
270     #endregion
271 }
View Code
原文地址:https://www.cnblogs.com/xiaotiannet/p/4024913.html