【截止2014-10-14】
网上搜索了很多篇文章,所提及的总共有两种方式:
- 1.Asp.Net模拟登陆;
例如:
实战ASP.NET访问共享文件夹(含详细操作步骤)
实现一个2008serve的IIS的虚拟目录(通过网络路径(UNC)的形式,共享在另外一个2008服务器上
- 2.调用Windows API 的 WNetAddConnection2 、WNetCancelConnection2函数;
例如:
ASP.NET网络映射驱动器无权限访问的解决方案
ASP.NET访问网络驱动器(映射磁盘)
相对来说,第一种方式是最直接的,且改动较小的。但不足之处就是比较依赖共享所在服务器(如果切换共享服务器地址,那么本地的用户名和密码都要作调整。);
而第二种方式缺点(个人感觉),API函数的不稳定、链接数超出限制、内存泄露等不稳定的问题(如果有哪位朋友有解决方案,还请告知,谢谢)。
ps:折腾了两天,先用第一种方式吧。附上一个第二种方式的辅助类。
#define CheckReturn using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; /// <summary> /// 网络资源访问 /// </summary> public class WNetConnectionHelper : IDisposable { /// <summary> /// 添加远程网络连接。 /// </summary> /// <param name="lpNetResource">是一个包含网络访问资源的结构,在这里作为参数用来指定详细的网络连接信息</param> /// <param name="lpPassword">指出访问远程计算机的密码。在Windows 95/98/Me 系统中,该值必须设置为NULL或空字符串</param> /// <param name="lpUsername">指出访问远程计算机的用户名。在Windows 95/98/Me 系统中,该值必须设置为NULL或空字符串</param> /// <param name="dwFlags">指出连接选项,包含六种设置</param> /// <returns>如果方法执行成功返回“NO_ERROR”即“0”。如果执行失败返回System Error Code。</returns> [DllImport("Mpr.dll", EntryPoint = "WNetAddConnection2")] /* private static extern uint WNetAddConnection2(NetResource lpNetResource, [MarshalAs(UnmanagedType.LPStr)]string lpPassword, [MarshalAs(UnmanagedType.LPStr)]string lpUsername, uint dwFlags); */ private static extern uint WNetAddConnection2(IntPtr lpNetResource, string lpPassword, string lpUsername, uint dwFlags); /// <summary> /// 释放存在的网络连接。 /// </summary> /// <param name="lpName">指定本地驱动器或远程共享资源</param> /// <param name="dwFlags">表示断开连接方式。设置 0 或CONNECT_UPDATE_PROFILE。</param> /// <param name="fForce">如果当前正在使用远程资源,是否进行强制断开连接。如果设置FALSE,在有远程资源使用的情况下关闭连接操作将会失败。</param> /// <returns>如果方法执行成功返回“NO_ERROR”即“0”。如果执行失败返回System Error Code。</returns> [DllImport("Mpr.dll", EntryPoint = "WNetCancelConnection2")] private static extern uint WNetCancelConnection2([MarshalAs(UnmanagedType.LPStr)]string lpName, uint dwFlags, int fForce); /// <summary> /// 获取网络错误的扩展错误信息 /// </summary> /// <param name="lpError">指定一个变量,用于装载网络错误代码。具体的代码由网络供应商决定</param> /// <param name="lpErrorBuf">指定一个字串缓冲区,用于装载网络错误的说明</param> /// <param name="nErrorBufSize">lpErrorBuf缓冲区包含的字符数量</param> /// <param name="lpNameBuf">用于装载网络供应商名字的字串缓冲区</param> /// <param name="nNameBufSize">lpNameBuf缓冲区的字符数量</param> /// <returns></returns> [DllImport("Mpr.dll", EntryPoint = "WNetGetLastError")] private static extern uint WNetGetLastError(ref uint lpError, [MarshalAs(UnmanagedType.LPStr)]ref string lpErrorBuf, long nErrorBufSize, [MarshalAs(UnmanagedType.LPStr)]ref string lpNameBuf, uint nNameBufSize); [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct NetResource { /// <summary> /// 指定枚举范围。设置RESOURCE_CONNECTED,RESOURCE_GLOBALNET,RESOURCE_REMEMBERED三值之一。 /// </summary> public int dwScope; /// <summary> /// 指定访问的资源类型。设置三个值之一。RESOURCETYPE_ANY表示所有资源;RESOURCETYPE_DISK表示磁盘资源;RESOURCETYPE_PRINT表示打印机。 /// </summary> public int dwType; /// <summary> /// 指出资源显示类型。RESOURCEDISPLAYTYPE_DOMAIN;RESOURCEDISPLAYTYPE_SERVER;RESOURCEDISPLAYTYPE_SHARE;RESOURCEDISPLAYTYPE_GENERIC。 /// </summary> public int dwDisplayType; /// <summary> /// 描述资源的使用方式。设置RESOURCEUSAGE_CONNECTABLE 或RESOURCEUSAGE_CONTAINER。 /// </summary> public int dwUsage; /// <summary> /// 同dwScope关联,指定本地映射。 /// </summary> //[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string lpLocalName; /// <summary> /// 远程访问文件夹路径。 /// </summary> //[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string lpRemoteName; /// <summary> /// 描述。 /// </summary> //[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string lpComment; /// <summary> /// 资源提供者,可以设置为NULL。 /// </summary> //[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string lpProvider; } public enum RESOURCE_SCOPE { RESOURCE_CONNECTED = 1, RESOURCE_GLOBALNET = 2, RESOURCE_REMEMBERED = 3, RESOURCE_RECENT = 4, RESOURCE_CONTEXT = 5 } public enum RESOURCE_TYPE { RESOURCETYPE_ANY = 0, RESOURCETYPE_DISK = 1, RESOURCETYPE_PRINT = 2, RESOURCETYPE_RESERVED = 8, } public enum RESOURCE_USAGE { RESOURCEUSAGE_CONNECTABLE = 1, RESOURCEUSAGE_CONTAINER = 2, RESOURCEUSAGE_NOLOCALDEVICE = 4, RESOURCEUSAGE_SIBLING = 8, RESOURCEUSAGE_ATTACHED = 16, RESOURCEUSAGE_ALL = (RESOURCEUSAGE_CONNECTABLE | RESOURCEUSAGE_CONTAINER | RESOURCEUSAGE_ATTACHED), } public enum RESOURCE_DISPLAYTYPE { RESOURCEDISPLAYTYPE_GENERIC = 0, RESOURCEDISPLAYTYPE_DOMAIN = 1, RESOURCEDISPLAYTYPE_SERVER = 2, RESOURCEDISPLAYTYPE_SHARE = 3, RESOURCEDISPLAYTYPE_FILE = 4, RESOURCEDISPLAYTYPE_GROUP = 5, RESOURCEDISPLAYTYPE_NETWORK = 6, RESOURCEDISPLAYTYPE_ROOT = 7, RESOURCEDISPLAYTYPE_SHAREADMIN = 8, RESOURCEDISPLAYTYPE_DIRECTORY = 9, RESOURCEDISPLAYTYPE_TREE = 10, RESOURCEDISPLAYTYPE_NDSCONTAINER = 11 } /// <summary> /// 添加远程网络连接。 /// </summary> /// <param name="netResource">是一个包含网络访问资源的结构,在这里作为参数用来指定详细的网络连接信息</param> /// <param name="username">指出访问远程计算机的用户名。在Windows 95/98/Me 系统中,该值必须设置为NULL或空字符串</param> /// <param name="password">指出访问远程计算机的密码。在Windows 95/98/Me 系统中,该值必须设置为NULL或空字符串</param> /// <returns>如果方法执行成功返回“NO_ERROR”即“0”。如果执行失败返回System Error Code。</returns> public static uint WNetAddConnection(NetResource netResource, string username, string password) { IntPtr ptr_netResource = IntPtr.Zero; try { //分配内存 ptr_netResource = System.Runtime.InteropServices.Marshal.AllocHGlobal(System.Runtime.InteropServices.Marshal.SizeOf(netResource)); System.Runtime.InteropServices.Marshal.StructureToPtr(netResource, ptr_netResource, false); uint result = WNetAddConnection2(ptr_netResource, password, username, 0); return result; } finally { if (ptr_netResource != IntPtr.Zero) System.Runtime.InteropServices.Marshal.FreeCoTaskMem(ptr_netResource); } /* uint result = WNetAddConnection2(netResource, password, username, 0); return result; */ } /// <summary> /// 添加远程网络连接。 /// </summary> /// <param name="username">指出访问远程计算机的用户名。在Windows 95/98/Me 系统中,该值必须设置为NULL或空字符串</param> /// <param name="password">指出访问远程计算机的密码。在Windows 95/98/Me 系统中,该值必须设置为NULL或空字符串</param> /// <param name="remoteName">远程访问文件夹路径。</param> /// <param name="localName">同dwScope关联,指定本地映射。</param> /// <returns>如果方法执行成功返回“NO_ERROR”即“0”。如果执行失败返回System Error Code。</returns> public static uint WNetAddConnection(string username, string password, string remoteName, string localName) { NetResource netResource = new NetResource(); netResource.dwScope = 2; //RESOURCE_GLOBALNET netResource.dwType = 1; //RESOURCETYPE_DISK netResource.dwDisplayType = 3; //RESOURCEDISPLAYTYPE_SHARE netResource.dwUsage = 1; //RESOURCEUSAGE_CONNECTABLE netResource.lpLocalName = localName; netResource.lpRemoteName = remoteName.TrimEnd(‘/‘); //netResource.lpRemoteName = lpComment; //netResource.lpProvider = null; uint result = WNetAddConnection(netResource, username, password); return result; } /// <summary> /// 添加远程网络连接。 /// </summary> /// <param name="name">指定本地驱动器或远程共享资源</param> /// <param name="flags">表示断开连接方式。设置 0 或CONNECT_UPDATE_PROFILE。</param> /// <param name="force">如果当前正在使用远程资源,是否进行强制断开连接。如果设置FALSE,在有远程资源使用的情况下关闭连接操作将会失败。</param> /// <returns>如果方法执行成功返回“NO_ERROR”即“0”。如果执行失败返回System Error Code。</returns> public static uint WNetCancelConnection(string name, uint flags, bool force) { uint nret = WNetCancelConnection2(name, flags, force ? 1 : 0); return nret; } #region SelfUsing bool connectSuccess = false; string username, password, remoteName, localName; private WNetConnectionHelper(string username, string password, string remoteName, string localName) { this.username = username; this.password = password; this.remoteName = remoteName; this.localName = localName; Close(); var code = WNetAddConnection(username, password, remoteName, localName); connectSuccess = code == 0; #if CheckReturn if (code != 0) { GetLastError(); throw new InvalidOperationException("The method WNetAddConnection return " + code); } #endif } private static void GetLastError() { uint lpError = 0; string lpErrorBuf = null; uint nErrorBufSize = 1024; string lpNameBuf = null; uint nNameBufSize = 1024; var errCode = WNetGetLastError(ref lpError, ref lpErrorBuf, nErrorBufSize, ref lpNameBuf, nNameBufSize); } public static WNetConnectionHelper New(string username, string password, string remoteName, string localName) { if (string.IsNullOrEmpty(remoteName)) throw new ArgumentException("remoteName"); return new WNetConnectionHelper(username, password, remoteName.TrimEnd(‘/‘), localName); } #endregion #region IDisposable 成员 public void Dispose() { if (!connectSuccess) return; if (string.IsNullOrEmpty(remoteName)) return; var code = Close(); #if CheckReturn if (code != 0) { GetLastError(); throw new InvalidOperationException("The method WNetCancelConnection return " + code); } #endif } private uint Close() { return WNetCancelConnection(remoteName, 1, true); } #endregion }
时间: 2024-11-10 07:56:34