在各種業務需求中,我們經常要訪問一個在網絡中的目錄,讀取其中的文件或者是在其目錄中創建文件,在.Net中我們主要使用mpr.dll中的WNetAddConnection2和WNetCancelConnection2來實現,下面是代碼引入。
[DllImport("mpr.dll")] private static extern int WNetAddConnection2(NetResource netResource, string password, string username, int flags); [DllImport("mpr.dll")] private static extern int WNetCancelConnection2(string name, int flags, bool force);
在上述代碼中使用到的NetResource 我們可以定義如下:
var netResource = new NetResource { Scope = ResourceScope.GlobalNetwork, ResourceType = ResourceType.Disk, DisplayType = ResourceDisplayType.Share, RemoteName = networkName };
參數RemoteName就是遠程網絡路徑。比如@"\\10.5.5.5\Public\Test"。
using System; using System.ComponentModel; using System.Runtime.InteropServices; using System.Net; namespace Phoenix.Modules.Common.Service.Uploads { public class ConnectToSharedFolder : IDisposable { readonly string _networkName; public ConnectToSharedFolder(string networkName, NetworkCredential credentials) { _networkName = networkName; var netResource = new NetResource { Scope = ResourceScope.GlobalNetwork, ResourceType = ResourceType.Disk, DisplayType = ResourceDisplayType.Share, RemoteName = networkName }; var userName = string.IsNullOrEmpty(credentials.Domain) ? credentials.UserName : $@"{credentials.Domain}\{credentials.UserName}"; var result = WNetAddConnection2( netResource, credentials.Password, userName, 0); if (result != 0) { throw new Win32Exception(result, "Error connecting to remote share"); } } ~ConnectToSharedFolder() { Dispose(false); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { WNetCancelConnection2(_networkName, 0, true); } [DllImport("mpr.dll")] private static extern int WNetAddConnection2(NetResource netResource, string password, string username, int flags); [DllImport("mpr.dll")] private static extern int WNetCancelConnection2(string name, int flags, bool force); [StructLayout(LayoutKind.Sequential)] public class NetResource { public ResourceScope Scope; public ResourceType ResourceType; public ResourceDisplayType DisplayType; public int Usage; public string LocalName; public string RemoteName; public string Comment; public string Provider; } public enum ResourceScope : int { Connected = 1, GlobalNetwork, Remembered, Recent, Context }; public enum ResourceType : int { Any = 0, Disk = 1, Print = 2, Reserved = 8, } public enum ResourceDisplayType : int { Generic = 0x0, Domain = 0x01, Server = 0x02, Share = 0x03, File = 0x04, Group = 0x05, Network = 0x06, Root = 0x07, Shareadmin = 0x08, Directory = 0x09, Tree = 0x0a, Ndscontainer = 0x0b } } }
引入ConnectToSharedFolder、NetResource、ResourceScope,就可以直接添加代碼寫入文件了。
using Phoenix.Modules.Common.Service.Uploads; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Text; using System.Threading.Tasks; namespace ConsoleApp4_networkDic { class Program { public static string networkPath = @"\\10.5.5.5\test"; static NetworkCredential credentials = new NetworkCredential(@"test", "May"); public static string myNetworkPath = string.Empty; static void Main(string[] args) { string filename = "test.txt"; FileUpload(filename); Console.ReadKey(); } public static void FileUpload(string UploadURL) { try { using (new ConnectToSharedFolder(networkPath, credentials)) { var fileList = Directory.GetDirectories(networkPath); foreach (var item in fileList) { if (item.Contains("{ClientDocument}")) { myNetworkPath = item; } } myNetworkPath = networkPath+@"\" + UploadURL; using (FileStream fileStream = File.Create(myNetworkPath)) { var file = System.Text.Encoding.UTF8.GetBytes("this is a test"); fileStream.Write(file, 0, file.Length); fileStream.Flush(); fileStream.Close(); } } } catch (Exception ex) { } } } }
這樣就可以訪問和讀取網絡中的路徑了,在測試中一直遇到在調用wnetaddconnection2方法的時候返回error 53的錯誤,看代碼中也是沒有錯誤,直接訪問所用的測試目標網絡文件也是可以的,然后再google一搜,就是我們在傳遞網絡目標文件路徑的時候后面不能有“\”,把“\”去掉然后再訪問就沒有問題了。
原文鏈接https://social.msdn.microsoft.com/Forums/windows/en-US/5f8224d4-c36a-4051-a8e5-7b2e4d817986/wnetaddconnection2-fails-with-error-code-53?forum=peertopeer。
