• ASP.NET访问网络驱动器(映射磁盘)


    也许很多朋友在做WEB项目的时候都会碰到这样一个需求:

    当用户上传文件时,需要将上传的文件保存到另外一台专门的文件服务器。

    要实现这样一个功能,有两种解决方案:

    方案一、在文件服务器上新建一站点,用来接收上传的文件,然后保存。

    方案二、将文件服务器的指定目录共享给WEB服务器,用来保存文件。

    方案一不用多说,应该是很简单的了,将上传文件的FORM表单的ACTION属性指向文件服务器上的站点即可,我们来重点说下方案二。

    也许你会说,其实方案二也很简单,在WEB服务器上做下磁盘映射,然后直接访问不就行了。其实不是这样的,IIS默认账户为NETWORK_SERVICE,该账户是没权限访问共享目录的,所以当你把站点部署到IIS上的时候,再访问映射磁盘就会报“找不到路径”的错误。所以,直接创建磁盘映射是行不通的,我们需要在程序中用指定账户创建映射,并用该账户运行IIS进程,下面来说下详细步骤及相关代码。

    1、在文件服务器上创建共享目录,并新建访问账户。

    比如共享目录为:\192.168.0.9share

    访问账户为:user-1 密码为:123456

    2、在WEB服务器上新建用户:user-1 密码为:123456,用户组选择默认的user组即可。

    3、在WEB项目中新建公共类WNetHelper

    [csharp] view plain copy
     
    1. using System.Runtime.InteropServices;  
    2.    
    3. public class WNetHelper  
    4. {  
    5.     [DllImport("mpr.dll", EntryPoint = "WNetAddConnection2")]  
    6.     private static extern uint WNetAddConnection2(NetResource lpNetResource, string lpPassword, string lpUsername, uint dwFlags);  
    7.    
    8.     [DllImport("Mpr.dll", EntryPoint = "WNetCancelConnection2")]  
    9.     private static extern uint WNetCancelConnection2(string lpName, uint dwFlags, bool fForce);  
    10.    
    11.     [StructLayout(LayoutKind.Sequential)]  
    12.     public class NetResource  
    13.     {  
    14.         public int dwScope;  
    15.    
    16.         public int dwType;  
    17.    
    18.         public int dwDisplayType;  
    19.    
    20.         public int dwUsage;  
    21.    
    22.         public string lpLocalName;  
    23.    
    24.         public string lpRemoteName;  
    25.    
    26.         public string lpComment;  
    27.    
    28.         public string lpProvider;  
    29.     }  
    30.    
    31.     /// <summary>  
    32.     /// 为网络共享做本地映射  
    33.    /// </summary>  
    34.     /// <param name="username">访问用户名(windows系统需要加计算机名,如:comp-1user-1)</param>  
    35.     /// <param name="password">访问用户密码</param>  
    36.     /// <param name="remoteName">网络共享路径(如:\192.168.0.9share)</param>  
    37.     /// <param name="localName">本地映射盘符</param>  
    38.     /// <returns></returns>  
    39.     public static uint WNetAddConnection(string username, string password, string remoteName, string localName)  
    40.     {  
    41.         NetResource netResource = new NetResource();  
    42.    
    43.         netResource.dwScope = 2;  
    44.         netResource.dwType = 1;  
    45.         netResource.dwDisplayType = 3;  
    46.         netResource.dwUsage = 1;  
    47.         netResource.lpLocalName = localName;  
    48.         netResource.lpRemoteName = remoteName.TrimEnd('\');  
    49.         uint result = WNetAddConnection2(netResource, password, username, 0);  
    50.    
    51.         return result;  
    52.     }  
    53.    
    54.     public static uint WNetCancelConnection(string name, uint flags, bool force)  
    55.     {  
    56.         uint nret = WNetCancelConnection2(name, flags, force);  
    57.    
    58.         return nret;  
    59.     }  
    60. }  

    4、为IIS指定运行账户user-1

    要实现此功能,有两种办法:

    a) 在web.config文件中的<system.web>节点下,添加如下配置:<identity impersonate="true" userName="user-1" password="123456" />

    b) 在WEB项目中添加公用类LogonImpersonate

    [csharp] view plain copy
     
    1. public class LogonImpersonate : IDisposable  
    2. {  
    3.     static public string DefaultDomain  
    4.     {  
    5.         get  
    6.         {  
    7.             return ".";  
    8.         }  
    9.     }  
    10.    
    11.     const int LOGON32_LOGON_INTERACTIVE = 2;  
    12.     const int LOGON32_PROVIDER_DEFAULT = 0;  
    13.    
    14.     [System.Runtime.InteropServices.DllImport("Kernel32.dll")]  
    15.     extern static int FormatMessage(int flag, ref   IntPtr source, int msgid, int langid, ref   string buf, int size, ref   IntPtr args);  
    16.    
    17.     [System.Runtime.InteropServices.DllImport("Kernel32.dll")]  
    18.     extern static bool CloseHandle(IntPtr handle);  
    19.    
    20.     [System.Runtime.InteropServices.DllImport("Advapi32.dll", SetLastError = true)]  
    21.     extern static bool LogonUser(  
    22.     string lpszUsername,  
    23.     string lpszDomain,  
    24.     string lpszPassword,  
    25.     int dwLogonType,  
    26.     int dwLogonProvider,  
    27.     ref   IntPtr phToken  
    28.     );  
    29.    
    30.     IntPtr token;  
    31.     System.Security.Principal.WindowsImpersonationContext context;  
    32.    
    33.     public LogonImpersonate(string username, string password)  
    34.     {  
    35.         if (username.IndexOf("\") == -1)  
    36.         {  
    37.             Init(username, password, DefaultDomain);  
    38.         }  
    39.         else  
    40.         {  
    41.             string[] pair = username.Split(new char[] { '\' }, 2);  
    42.             Init(pair[1], password, pair[0]);  
    43.         }  
    44.     }  
    45.     public LogonImpersonate(string username, string password, string domain)  
    46.     {  
    47.         Init(username, password, domain);  
    48.     }  
    49.     void Init(string username, string password, string domain)  
    50.     {  
    51.         if (LogonUser(username, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref   token))  
    52.         {  
    53.             bool error = true;  
    54.             try  
    55.             {  
    56.                 context = System.Security.Principal.WindowsIdentity.Impersonate(token);  
    57.                 error = false;  
    58.             }  
    59.             finally  
    60.             {  
    61.                 if (error)  
    62.                     CloseHandle(token);  
    63.             }  
    64.         }  
    65.         else  
    66.         {  
    67.             int err = System.Runtime.InteropServices.Marshal.GetLastWin32Error();  
    68.    
    69.             IntPtr tempptr = IntPtr.Zero;  
    70.             string msg = null;  
    71.    
    72.             FormatMessage(0x1300, ref   tempptr, err, 0, ref   msg, 255, ref   tempptr);  
    73.    
    74.             throw (new Exception(msg));  
    75.         }  
    76.     }  
    77.     ~LogonImpersonate()  
    78.     {  
    79.         Dispose();  
    80.     }  
    81.     public void Dispose()  
    82.     {  
    83.         if (context != null)  
    84.         {  
    85.             try  
    86.             {  
    87.                 context.Undo();  
    88.             }  
    89.             finally  
    90.             {  
    91.                 CloseHandle(token);  
    92.                 context = null;  
    93.             }  
    94.         }  
    95.     }  
    96. }  

    在访问映射磁盘之前首先调用此类为IIS更换运行用户:LogonImpersonate imper = new LogonImpersonate("user-1", "123456");

    5、在访问共享目录前,调用WNetHelper.WNetAddConnection,添加磁盘映射

    [csharp] view plain copy
     
    1. public static bool CreateDirectory(string path)  
    2. {  
    3.     uint state = 0;  
    4.     if (!Directory.Exists("Z:"))  
    5.     {  
    6.         state = WNetHelper.WNetAddConnection(@"comp-1user-1", "123456", @"\192.168.0.9share", "Z:");  
    7.     }  
    8.     if (state.Equals(0))  
    9.     {  
    10.         Directory.CreateDirectory(path);  
    11.         return true;  
    12.     }  
    13.     else  
    14.     {  
    15.         throw new Exception("添加网络驱动器错误,错误号:" + state.ToString());  
    16.     }  
    17. }  

    6、完成。

    简洁代码就是:

    LogonImpersonate imper = new LogonImpersonate("user-1", "123456");

    WNetHelper.WNetAddConnection(@"comp-1user-1", "123456", @"\192.168.0.9share", "Z:");
    Directory.CreateDirectory(@"Z: ewfolder");

    file1.SaveAs(@"Z: ewfolder est.jpg");

  • 相关阅读:
    解决 Windows 资源管理器 CPU 占用率很高的问题
    彻底卸载Cygwin
    Cygwin 快速镜像站点
    解决 cygwin 在 win10 下中文显示乱码的问题
    酷派大神 F1 连接调试,日志获取的方法
    陌路
    游戏开发中自定义脚本与配置
    在 cygwin 的环境下调用 libgdx gdx-tools
    在 cygwin 的环境下使用 git 的时候中文编码的问题
    对 android apk 进行重新签名操作
  • 原文地址:https://www.cnblogs.com/kylin2016/p/5848232.html
Copyright © 2020-2023  润新知