您好,登錄后才能下訂單哦!
這篇文章主要介紹了C#訪問(wèn)遠(yuǎn)程主機(jī)資源的方法有哪些,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
一、調(diào)用Net use命令
// 使用方法: //if (Connect("192.168.1.48", "用戶名", "密碼")) //{ // File.Copy(@"\\192.168.1.48\共享目錄\test.txt", @"e:\\test.txt", true); //} public bool Connect(string remoteHost, string userName, string passWord) { bool Flag = true; Process proc = new Process(); proc.StartInfo.FileName = "cmd.exe"; proc.StartInfo.UseShellExecute = false; proc.StartInfo.RedirectStandardInput = true; proc.StartInfo.RedirectStandardOutput = true; proc.StartInfo.RedirectStandardError = true; proc.StartInfo.CreateNoWindow = true; try { proc.Start(); string command = @"net use \\" + remoteHost + " " + passWord + " " + " /user:" + userName + ">NUL"; proc.StandardInput.WriteLine(command); command = "exit"; proc.StandardInput.WriteLine(command); while (proc.HasExited == false) { proc.WaitForExit(1000); } string errormsg = proc.StandardError.ReadToEnd(); if (errormsg != "") Flag = false; proc.StandardError.Close(); } catch (Exception ex) { Flag = false; } finally { proc.Close(); proc.Dispose(); } return Flag; }
二、調(diào)用WNetAddConnection2、WNetAddConnection3或者NetUseAdd函數(shù),進(jìn)行磁盤映射。
using System;using System.Collections.Generic;using System.Text; using System.Runtime.InteropServices; namespace WindowsApplication1{ public class MyMap { [DllImport("mpr.dll", EntryPoint = "WNetAddConnection2")] public static extern uint WNetAddConnection2( [In] NETRESOURCE lpNetResource, string lpPassword, string lpUsername, uint dwFlags); [DllImport("Mpr.dll")] public static extern uint WNetCancelConnection2( string lpName, uint dwFlags, bool fForce); [StructLayout(LayoutKind.Sequential)] public class NETRESOURCE { public int dwScope; public int dwType; public int dwDisplayType; public int dwUsage; public string LocalName; public string RemoteName; public string Comment; public string Provider; } // remoteNetworkPath format: @"\\192.168.1.48\sharefolder" // localDriveName format: @"E:" public static bool CreateMap(string userName, string password, string remoteNetworkPath, string localDriveName) { NETRESOURCE myNetResource = new NETRESOURCE(); myNetResource.dwScope = 2; //2:RESOURCE_GLOBALNET myNetResource.dwType = 1; //1:RESOURCETYPE_ANY myNetResource.dwDisplayType = 3; //3:RESOURCEDISPLAYTYPE_GENERIC myNetResource.dwUsage = 1; //1: RESOURCEUSAGE_CONNECTABLE myNetResource.LocalName = localDriveName; myNetResource.RemoteName = remoteNetworkPath; myNetResource.Provider = null; uint nret = WNetAddConnection2(myNetResource, password, userName, 0); if (nret == 0) return true; else return false; } // localDriveName format: @"E:" public static bool DeleteMap(string localDriveName) { uint nret = WNetCancelConnection2(localDriveName, 1, true); if (nret == 0) return true; else return false; } public void test() { // 注意: // remote、local、username的格式一定要正確,否則可能出現(xiàn)錯(cuò)誤 string remote = @"\\192.168.1.48\generals"; string local = @"P:"; string username = @"Domain\UserName"; string password = @"Password"; bool ret = MyMap.CreateMap(username, password, remote, local); if (ret) { //do what you want: // ... //File.Copy("q:\\test.htm", "c:\\test.htm"); MyMap.DeleteMap(local); } } }}
三、使用WebClient類
由于WebClient類可以上傳下載文件,并且支持以http:、https:和file:開頭的URI,所以可以用WebClient類來(lái)傳輸文件。
添加System.Net命名空間后使用如下代碼下載文件:
private void Test1() { try { WebClient client = new WebClient(); NetworkCredential cred = new NetworkCredential("username", "password", "172.16.0.222"); client.Credentials = cred; client.DownloadFile("file://172.16.0.222/test/111.txt", "111.txt"); } catch (Exception ex) { // 如果網(wǎng)絡(luò)很慢,而文件又很大,這時(shí)可能有超時(shí)異常(Time out)。 } } public void Test2() { try { WebClient client = new WebClient(); NetworkCredential cred = new NetworkCredential("username", "password", "domain"); client.Credentials = cred; client.DownloadFile("file://172.16.0.222/test/111.txt", "111.txt"); } catch (Exception ex) { // 如果網(wǎng)絡(luò)很慢,而文件又很大,這時(shí)可能有超時(shí)異常(Time out)。 } }
類似的還可以試試WebRequest、FileWebRequest等:
WebRequest req = WebRequest.Create("file://138.12.12.14/generals/test.htm"); NetworkCredential cred = new NetworkCredential("username", "password", "IP"); req.Credentials = cred; WebResponse response = req.GetResponse(); Stream strm = response.GetResponseStream(); StreamReader r = new StreamReader(strm); ... ...
四、角色模擬
/// <summary> /// 身份模擬實(shí)現(xiàn)遠(yuǎn)程資源訪問(wèn) /// </summary> public class FileImpersonation { // logon types const int LOGON32_LOGON_INTERACTIVE = 2; const int LOGON32_LOGON_NETWORK = 3; const int LOGON32_LOGON_NEW_CREDENTIALS = 9; // logon providers const int LOGON32_PROVIDER_DEFAULT = 0; const int LOGON32_PROVIDER_WINNT50 = 3; const int LOGON32_PROVIDER_WINNT40 = 2; const int LOGON32_PROVIDER_WINNT35 = 1; [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern int LogonUser(string lpszUserName, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken); [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern int DuplicateToken(IntPtr hToken, int impersonationLevel, ref IntPtr hNewToken); [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern bool RevertToSelf(); [DllImport("kernel32.dll", CharSet = CharSet.Auto)] public static extern bool CloseHandle(IntPtr handle); private WindowsImpersonationContext impersonationContext; /// <summary> /// 身份模擬 /// </summary> /// <param name="userName">獨(dú)立服務(wù)器用IP,域環(huán)境就用域名</param> /// <param name="domain"></param> /// <param name="password"></param> /// <returns></returns> public bool impersonateValidUser(string userName, string domain, string password) { WindowsIdentity tempWindowsIdentity; IntPtr token = IntPtr.Zero; IntPtr tokenDuplicate = IntPtr.Zero; if (RevertToSelf()) { // 這里使用LOGON32_LOGON_NEW_CREDENTIALS來(lái)訪問(wèn)遠(yuǎn)程資源。 // 如果要(通過(guò)模擬用戶獲得權(quán)限)實(shí)現(xiàn)服務(wù)器程序,訪問(wèn)本地授權(quán)數(shù)據(jù)庫(kù)可 // 以用LOGON32_LOGON_INTERACTIVE if (LogonUser(userName, domain, password, LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_DEFAULT, ref token) != 0) { if (DuplicateToken(token, 2, ref tokenDuplicate) != 0) { tempWindowsIdentity = new WindowsIdentity(tokenDuplicate); impersonationContext = tempWindowsIdentity.Impersonate(); if (impersonationContext != null) { AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal); IPrincipal pr = System.Threading.Thread.CurrentPrincipal; IIdentity id = pr.Identity; CloseHandle(token); CloseHandle(tokenDuplicate); return true; } } } } if (token != IntPtr.Zero) CloseHandle(token); if (tokenDuplicate != IntPtr.Zero) CloseHandle(tokenDuplicate); return false; } /// <summary> /// 取消模擬身份 /// </summary> public void undoImpersonation() { impersonationContext.Undo(); } /// <summary> /// /// </summary> /// <param name="domain">獨(dú)立服務(wù)器用IP,域環(huán)境就用域名</param> /// <param name="username"></param> /// <param name="password"></param> /// <param name="act">需要執(zhí)行的操作</param> public void ImpersonateFunc(string username, string domain, string password, Action act) { bool isImpersonated = false; try { if (impersonateValidUser(username, domain, password)) { isImpersonated = true; //File.Copy(@"\\192.168.1.48\generals\now.htm", "c:\\now.htm", true); act(); } } catch (Exception ex) { Console.WriteLine(ex.ToString()); } finally { if (isImpersonated) undoImpersonation(); } } // } FileImpersonation imp = new FileImpersonation(); imp.ImpersonateFunc("Administrator", "192.168.0.125", "xxxx", () => { var source = new DirectoryInfo(@"D:\HR"); string targetFolder = @"\\192.168.0.125\d$\HR"; if (!Directory.Exists(targetFolder)) { Directory.CreateDirectory(targetFolder); } foreach (FileInfo item in source.GetFiles()) { string targertFile = Path.Combine(targetFolder, item.Name); File.Copy(item.FullName, targertFile, true); } });
五、比較
方法一通過(guò)調(diào)用Shell命令Net Use實(shí)現(xiàn),有點(diǎn)笨拙。
方法二和方法一有些相似之處。映射遠(yuǎn)程資源,然后訪問(wèn)。
方法三由于會(huì)有超時(shí)異常出現(xiàn),所以在網(wǎng)絡(luò)速度快、傳輸小文件時(shí)是可以的。
方法四通過(guò)身份模擬實(shí)現(xiàn)遠(yuǎn)程資源訪問(wèn)。一些服務(wù)器進(jìn)程就是通過(guò)這種方式運(yùn)行的。這種方法也是我的最愛。
六、要注意的地方
關(guān)于這幾種方法,google后都可以找到一些文章。但是等到自己實(shí)際測(cè)試時(shí),有時(shí)會(huì)出現(xiàn)各種小錯(cuò)誤,
這些錯(cuò)誤基本來(lái)源于兩方面:
1、函數(shù)的參數(shù)選擇有問(wèn)題,和自己的環(huán)境不相符。
比如
public static extern int LogonUser(String lpszUserName, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
中的dwLogonType,要訪問(wèn)遠(yuǎn)程資源就要用LOGON32_LOGON_NEW_CREDENTIALS,
要模擬本機(jī)用戶就要用LOGON32_LOGON_INTERACTIVE。
2、函數(shù)的參數(shù)格式有問(wèn)題。
a、比如
public static extern int LogonUser(String lpszUserName, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
中的lpszUserName、lpszDomain、lpszPassword就要寫清楚。
我就在這遇到過(guò)問(wèn)題,第一次測(cè)試時(shí),遠(yuǎn)程服務(wù)器就是一臺(tái)獨(dú)立的文件服務(wù)器,這是我的調(diào)用方式:
LogonUser("myname", "192.168.1.48", "password", LOGON32_LOGON_NEW_CREDENTIALS,
LOGON32_PROVIDER_DEFAULT, ref token);
第二次測(cè)試時(shí),遠(yuǎn)程服務(wù)器是域MyDomain中的一個(gè)成員服務(wù)器,提供文件服務(wù)。這時(shí)代碼就應(yīng)該是:
LogonUser("myname", "MyDomain", "password", LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_DEFAULT, ref token);
注意,代碼中是MyDomain而不是IP地址。
b、再如:
參考上面代碼
string remote = @"\\192.168.1.48\generals"; string local = @"P:"; string username = @"Domain\UserName"; string password = @"Password";
如果@"\\192.168.1.48\generals"變成@"\\192.168.1.48\generals\”就會(huì)出錯(cuò);
如果是域中的用戶,那么把@"Domain\UserName"變成@"UserName"就會(huì)出錯(cuò)。
感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“C#訪問(wèn)遠(yuǎn)程主機(jī)資源的方法有哪些”這篇文章對(duì)大家有幫助,同時(shí)也希望大家多多支持億速云,關(guān)注億速云行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來(lái)學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。