首页 > 代码库 > IIS/ASP.NET访问共享文件夹的可用方式

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

【截止2014-10-14】

 

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

  1. 1.Asp.Net模拟登陆;

例如:

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

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

 

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

例如:

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

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

 

 

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

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

 

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

 

 

#define CheckReturnusing 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}

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