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 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

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

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

转载:http://www.cnblogs.com/dudu/archive/2012/03/27/asp_net_share_folder.html 博客园找找看(http://zzk.cnblogs.com)的索引文件占用空间太大,需要移至另外一台服务器,所以要解决"在ASP.NET中通过共享文件夹访问索引文件"的问题. 假设找找看的ASP.NET程序在A服务器,索引文件在B服务器的ZzkIndex共享文件夹中,访问地址是\\192.168.18.18\ZzkIndex\.要实现就

IIS7站点/虚拟目录中访问共享文件夹(转)

IIS7.0站点/虚拟目录中访问共享 目的:实现一个2008serve的IIS的虚拟目录(通过网络路径(UNC)的形式,共享在另外一个2008服务器上) 准备工作 1.运行组策略编辑器(gpedit.msc) 找到本地安全策略-本地策略-安全选项子项中的:网络安全:LAN管理器身份验证级别,默认是“没有定义”,更改为“发送LM和NTLM响应”. 2.共享资源服务器为 ShareServer,IP地址为:192.168.100.10: 3.Web服务器为 WebServer,IP地址为:192.1

VirtualBox中的Ubuntu没有权限访问共享文件夹/media/sf_bak

之前已经搞定可以自动共享文件夹了,但是现在发现无法去访问,非root用户下,使用“ls /media/sf_bak”提示没有权限,当然如果切换到root,是可以的. [解决过程]1.把普通用户名加入到vboxsf之中.因为你的用户名不在vboxsf这个用户组.下面添加boarmy到vboxsf这个用户组.[email protected]:~$ sudo adduser boarmy vboxsf正在添加用户"boarmy"到"vboxsf"组...正在将用户“bo

切换用户访问共享文件夹

1.现在登录用户A访问了共享文件夹 2.删除已登录的访问账号 3.再次访问共享文件夹,提示输入密码 4.使用命令进行切换访问共享文件夹 5.切换用户访问成功 6.如果之前登录时候,选择了记住密码 7.进入用户账户-管理您的凭据 8.从保管库中删除 9.确认删除 10.如果删除凭据后,仍可访问共享文件夹,再运行一次删除命令(发现还是有连接存在的)即可

可以PING通IP,PING名字不通,可以远程,但不能访问共享文件夹?

问题现象:可以PING通IP,PING名字不通,可以远程,但不能访问共享文件夹? 问题原因:目标主机中NetLogon服务未启动. 问题处理:远程打开目标主机,“我的电脑-管理-服务-启动(改为自动)”  . 问题跟踪: ①错误表现 CMD-"net use \\192.168.1.2" 发生系统错误1792. 试图登录,但是网络登录服务没有启动. ②正确表现 CMD-"net use \\192.168.1.2" 命令成功完成.

清除在Windows下访问共享文件夹时的登录信息

清除在Windows下访问共享文件夹时的登录信息 在实际工作中,经常需要访问局域网内其他机子上的共享文件夹,例如\\192.168.1.100\d$ , 首次访问时,需要输入用户名和密码才可以进入,即使没有勾选”保存密码”选项,下次登录时也会直接进入,虽然这个功能方便实用,但是当需要切换到另外 一个账号时,就不知所措了. 那么:如何才能清除本机Windows环境下访问这些共享文件夹时的登录信息(用户名和密码)呢? 下面给大家介绍一下. 一.命令行(cmd窗口)操作 当在命令提示窗口输入net u

(转)WIN7更改用户名访问共享文件夹

原文地址: http://ryy8013.blog.163.com/blog/static/71729589201210610533778/ 一直以来,windows7客户端访问windows server2008上的共享文件夹,第一次输入用户名和密码后,即时不勾选“保存密码”选型,在重新登录系统之前,客户端总会以曾经登陆过的用户来进入共享文件夹,而不会弹出输入用户名和密码的对话框,让用户重新以新用户的身份来访问共享文件夹. 经过长期测试,发现以下办法有效,特记录之: 1, 清空已有共享连接 n

samba服务匿名访问共享文件夹

1 安装samba文件包,在etc目录下可以看到有三个文件 2 将smb.conf进行备份,再把该文件进行过滤,可以看到界面上的注释都被过滤掉,只剩下可配置文件 3 现在对文件开始进行配置,首先将user改为share,表示匿名访问 4 接着在文件底端添加想要共享的文件,这里可以参照上面的模板进行配置,这里包括文件名,文件路径,访问权限,读写权限,文件自身权限,文件夹自身权限,配置完成后保存退出 5 保存退出后,在opt下创建一个abc作为共享文件的路径,接着把文件权限放到最大,接着输入命令se

samba服务用虚拟用户名访问共享文件夹

1接着之前的本地用户访问共享文件夹继续做实验,想要用虚拟用户名进行登录就需要对smbusers这个文件进行配置 2 进入该文件可以看到这里的每一个用户都对应着一个虚拟名字,这里我给zhangsan,lisi两个用户设置两个虚拟名字,然后用虚拟名称进行登录 3 虚拟名称配置完成后还需要在smb.conf文件中添加username map这条命令,注意之后的路径一定不能写错,配置完成后保存退出,在重新启动服务器 4 用zhangsan的虚拟名称进行登录,进来可以看到zhangsan的家目录 5 再用