ASP.NET开发中使用网络驱动器存取文件
参考http://www.cnblogs.com/sqzhuyi/archive/2011/01/15/aspnet-remote.html
1、需求
做WEB项目的时候都会碰到这样一个需求:
当用户上传文件时,需要将上传的文件保存到另外一台专门的文件服务器。
2、解决方案
方案一、在文件服务器上新建一站点,用来接收上传的文件,然后保存。(将上传文件的FORM表单的ACTION属性指向文件服务器上的站点即可)
方案二、将文件服务器的指定目录共享给WEB服务器,用来保存文件。
3、实现步骤
问题(在WEB服务器上做下磁盘映射,IIS默认账户为NETWORK_SERVICE,该账户是没权限访问共享目录的,所以当你把站点部署到IIS上的时候,再访问映射磁盘就会报“找不到路径”的错误)
(1)在文件服务器上创建共享目录,并新建访问账户。
比如共享目录为:\\192.168.0.9\share
访问账户为:user-1 密码为:123456
确保在WEB服务器上可以访问到这个目录
(2)建立公共类
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace Gloable 7 { 8 //======================================== 9 // Description: 10 // Author: 11 // DateTime: 2016/8/12 12:23:16 12 //======================================== 13 public class LogonImpersonate : IDisposable 14 { 15 static public string DefaultDomain 16 { 17 get 18 { 19 return "."; 20 } 21 } 22 23 const int LOGON32_LOGON_INTERACTIVE = 2; 24 const int LOGON32_PROVIDER_DEFAULT = 0; 25 26 [System.Runtime.InteropServices.DllImport("Kernel32.dll")] 27 extern static int FormatMessage(int flag, ref IntPtr source, int msgid, int langid, ref string buf, int size, ref IntPtr args); 28 29 [System.Runtime.InteropServices.DllImport("Kernel32.dll")] 30 extern static bool CloseHandle(IntPtr handle); 31 32 [System.Runtime.InteropServices.DllImport("Advapi32.dll", SetLastError = true)] 33 extern static bool LogonUser( 34 string lpszUsername, 35 string lpszDomain, 36 string lpszPassword, 37 int dwLogonType, 38 int dwLogonProvider, 39 ref IntPtr phToken 40 ); 41 42 IntPtr token; 43 System.Security.Principal.WindowsImpersonationContext context; 44 45 public LogonImpersonate(string username, string password) 46 { 47 if (username.IndexOf("\\") == -1) 48 { 49 Init(username, password, DefaultDomain); 50 } 51 else 52 { 53 string[] pair = username.Split(new char[] { '\\' }, 2); 54 Init(pair[1], password, pair[0]); 55 } 56 } 57 public LogonImpersonate(string username, string password, string domain) 58 { 59 Init(username, password, domain); 60 } 61 void Init(string username, string password, string domain) 62 { 63 if (LogonUser(username, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token)) 64 { 65 bool error = true; 66 try 67 { 68 context = System.Security.Principal.WindowsIdentity.Impersonate(token); 69 error = false; 70 } 71 finally 72 { 73 if (error) 74 CloseHandle(token); 75 } 76 } 77 else 78 { 79 int err = System.Runtime.InteropServices.Marshal.GetLastWin32Error(); 80 81 IntPtr tempptr = IntPtr.Zero; 82 string msg = null; 83 84 FormatMessage(0x1300, ref tempptr, err, 0, ref msg, 255, ref tempptr); 85 86 throw (new Exception(msg)); 87 } 88 } 89 ~LogonImpersonate() 90 { 91 Dispose(); 92 } 93 public void Dispose() 94 { 95 if (context != null) 96 { 97 try 98 { 99 context.Undo(); 100 } 101 finally 102 { 103 CloseHandle(token); 104 context = null; 105 } 106 } 107 } 108 109 110 111 } 112 }
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Runtime.InteropServices; 6 7 namespace Gloable 8 { 9 //======================================== 10 // Description: 11 // Author: 12 // DateTime: 2016/8/12 12:21:45 13 //======================================== 14 public class WNetHelper 15 { 16 17 [DllImport("mpr.dll", EntryPoint = "WNetAddConnection2")] 18 private static extern uint WNetAddConnection2(NetResource lpNetResource, string lpPassword, string lpUsername, uint dwFlags); 19 20 [DllImport("Mpr.dll", EntryPoint = "WNetCancelConnection2")] 21 private static extern uint WNetCancelConnection2(string lpName, uint dwFlags, bool fForce); 22 23 [StructLayout(LayoutKind.Sequential)] 24 public class NetResource 25 { 26 public int dwScope; 27 28 public int dwType; 29 30 public int dwDisplayType; 31 32 public int dwUsage; 33 34 public string lpLocalName; 35 36 public string lpRemoteName; 37 38 public string lpComment; 39 40 public string lpProvider; 41 } 42 43 /// <summary> 44 /// 为网络共享做本地映射 45 /// </summary> 46 /// <param name="username">访问用户名(windows系统需要加计算机名,如:comp-1\user-1)</param> 47 /// <param name="password">访问用户密码</param> 48 /// <param name="remoteName">网络共享路径(如:\\192.168.0.9\share)</param> 49 /// <param name="localName">本地映射盘符</param> 50 /// <returns></returns> 51 public static uint WNetAddConnection(string username, string password, string remoteName, string localName) 52 { 53 NetResource netResource = new NetResource(); 54 55 netResource.dwScope = 2; 56 netResource.dwType = 1; 57 netResource.dwDisplayType = 3; 58 netResource.dwUsage = 1; 59 netResource.lpLocalName = localName; 60 netResource.lpRemoteName = remoteName.TrimEnd('\\'); 61 uint result = WNetAddConnection2(netResource, password, username, 0); 62 63 return result; 64 } 65 66 public static uint WNetCancelConnection(string name, uint flags, bool force) 67 { 68 uint nret = WNetCancelConnection2(name, flags, force); 69 70 return nret; 71 } 72 73 } 74 }
(3)实现代码
1 using System; 2 using System.Collections.Generic; 3 using System.Data; 4 using System.Diagnostics; 5 using System.Drawing; 6 using System.IO; 7 using System.Linq; 8 using System.Web; 9 using System.Web.UI; 10 using System.Web.UI.WebControls; 11 using Microsoft.Win32; 12 using System.IO; 13 14 15 namespace CloudCustoms.jiekou 16 { 17 public partial class IKEAList : System.Web.UI.Page 18 { 19 private static string username = "user_ikea"; 20 private static string AreaUsername = @"KEYUE83\user_ikea"; 21 private static string pwd = "user_ikea_keyue"; 22 23 24 protected void btnDownload_Click1(object sender, EventArgs e) 25 { 26 //为IIS制定账号 27 Gloable.LogonImpersonate imper = new Gloable.LogonImpersonate(username, pwd); 28 Gloable.WNetHelper.WNetAddConnection(AreaUsername, pwd, @"\\192.168.100.83\swbPDF", "X:"); 29 Gloable.WNetHelper.WNetAddConnection(AreaUsername, pwd, @"\\192.168.100.83\psrPDF", "Y:"); 30 31 string coolist = string.Empty; 32 string swblist = string.Empty; 33 34 //遍历服务器指定文件夹下的所有文件 35 string serverPath = @"X:"; 36 37 //创建临时文件夹 38 string tempName = DateTime.Now.ToString("yyyyMMddHHmmss"); 39 string tempFolder = Path.Combine(serverPath, tempName); 40 Directory.CreateDirectory(tempFolder); 41 42 43 for (int i = 0; i < gv_ikealist.Rows.Count; i++) 44 { 45 CheckBox cb = gv_ikealist.Rows[i].Cells[0].FindControl("ckbSelect") as CheckBox; 46 if (cb.Checked) 47 { 48 HiddenField hidcoo = gv_ikealist.Rows[i].Cells[11].FindControl("hidCOO") as HiddenField; 49 HiddenField hidswb = gv_ikealist.Rows[i].Cells[12].FindControl("hidswb") as HiddenField; 50 51 if (!string.IsNullOrEmpty(hidcoo.Value.Trim())) 52 { 53 string filename = hidcoo.Value.Trim().Replace(@"www.52xinhai.com\ikea\psrPDF\", ""); 54 File.Copy(@"Y:\" + filename, tempFolder + "/" + filename); 55 } 56 57 58 if (!string.IsNullOrEmpty(hidswb.Value.Trim())) 59 { 60 string filename = hidswb.Value.Trim().Replace(@"www.52xinhai.com\ikea\swbPDF\", ""); 61 File.Copy(@"X:\" + filename, tempFolder + "/" + filename); 62 } 63 } 64 } 65 66 //产生RAR文件,及文件输出 67 string rarpath = serverPath + @"\" + tempName + ".rar"; 68 string err = string.Empty; 69 Gloable.ZipFileClass zip = new Gloable.ZipFileClass(); 70 zip.ZipFile(tempFolder, rarpath, out err); 71 DownloadRAR(rarpath); 72 73 } 74 75 /// <summary> 76 /// 下载生成的RAR文件 77 /// </summary> 78 private void DownloadRAR(string file) 79 { 80 FileInfo fileInfo = new FileInfo(file); 81 Response.Clear(); 82 Response.ClearContent(); 83 Response.ClearHeaders(); 84 Response.AddHeader("Content-Disposition", "attachment;filename=" + fileInfo.Name); 85 Response.AddHeader("Content-Length", fileInfo.Length.ToString()); 86 Response.AddHeader("Content-Transfer-Encoding", "binary"); 87 Response.ContentType = "application/octet-stream"; 88 Response.ContentEncoding = System.Text.Encoding.GetEncoding("gb2312"); 89 Response.WriteFile(fileInfo.FullName); 90 Response.Flush(); 91 string tempPath = file.Substring(0, file.LastIndexOf(".rar")); 92 //删除临时目录下的所有文件 93 DeleteFiles(tempPath); 94 //删除空目录 95 Directory.Delete(tempPath); 96 //删除压缩文件 97 File.Delete(file); 98 99 Response.End(); 100 } 101 102 103 /// <summary> 104 /// 删除临时目录下的所有文件 105 /// </summary> 106 /// <param name="tempPath">临时目录路径</param> 107 private void DeleteFiles(string tempPath) 108 { 109 DirectoryInfo directory = new DirectoryInfo(tempPath); 110 try 111 { 112 foreach (FileInfo file in directory.GetFiles()) 113 { 114 if (file.Attributes.ToString().IndexOf("ReadOnly") != -1) 115 { 116 file.Attributes = FileAttributes.Normal; 117 } 118 File.Delete(file.FullName); 119 } 120 } 121 catch (Exception) 122 { 123 throw; 124 } 125 } 126 127 } 128 }