A file in a shared directory that accesses a remote host is recently implemented. A permissions issue was encountered. Google a bit, found a few solutions, recorded as follows:
First, call the net USE command
How to use://if (Connect ("192.168.1.48", "username", "password"))//{//File.Copy (@ "\\192.168.1.48\ shared directory \te St.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; }
Second, call the WNetAddConnection2, WNetAddConnection3, or NetUseAdd functions for disk mapping.
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 LpN Etresource, String Lppassword, String lpusername, uint dwFlags); [DllImport ("Mpr.dll")] public static extern uint WNetCancelConnection2 (string lpname, uint D Wflags, 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, St Ring 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 must be in the correct format, otherwise error may occur str ing 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 want://...//file.copy ("q:\\test.htm", "C:\\test.htm"); Mymap.deletemap (local); } } }}
Third, use the WebClient class
because the WebClient class can upload a download file, and it supports URIs that start with http:, https:, and file: You can use the WebClient class to transfer files.
After adding the System.Net namespace, download the file using the following code:
private void Test1 () {try {WebClient CLI ent = 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) {//If the network is slow and the file is large, there may be a timeout exception (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) {//If the network is slow and the file is large, there may be a timeout exception (time out). } }
Similar can also try WebRequest, filewebrequest, etc.:
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); ... ...
Four, role simulation
<summary>///Identity simulation for remote resource access///</summary> public class Fileimpersonation {//Logon Typ es 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 DwL Ogonprovider, ref IntPtr phtoken); [DllImport ("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern int DuplicateToken (in Tptr 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>///Identity simulation///</summary>//<param name= "UserName" > Standalone server with IP, domain environment with domain name &L t;/param>//<param name= "domain" ></param>///<param name= "password" ></param> <returns></returns> public bool impersonateValidUser (string userName, String domain, string p Assword) {WindowsIdentity tempwindowsidentity; IntPtr token = IntPtr.Zero; IntPtr tokenduplicate = IntPtr.Zero; if (RevertToSelf ()) {//Use logon32_logon_new_credentials here to access remote resources. If you want to implement a server program (by impersonating a user), access the local authorization database to To use 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 (tokend uplicate); impersonationcontext = Tempwindowsidentity.impersonate (); if (impersonationcontext! = null) {AppDomain.CurrentDomain.SetPrincipal Policy (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>//Cancel Impersonation identity///</summary> public void undoimpersonation () { Impersonationcontext.undo (); }//<summary>///</summary>/<param name= "domain" > standalone server IP, domain environment Name </param>//<param name= "username" ></param>//<param name= "password" ></param& Gt <param name= "Act" > Actions to be performed </param> public void Impersonatefunc (string username, string domain, Strin G 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 Directoryi NFO (@ "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); } });
V. Comparison
Method one is somewhat clumsy by invoking the shell command net use implementation.
There are some similarities between method two and method one. Map the remote resource and then access it.
Method three because there will be a time-out exception, so the network speed, the transfer of small files is possible.
Method four realizes remote resource access through identity simulation. Some server processes run in this way. This method is also my favorite.
Six, the place to pay attention to
Google can find some articles about these options. But when you actually test it, there are a few small errors that sometimes occur,
These errors come from two main aspects:
1, the function parameter choice has the question, and own environment does not match.
Like what
public static extern int LogonUser (String lpszusername, string lpszdomain, string lpszpassword, int dwLogonType, int dwlogonprovider, ref IntPtr phtoken);
dwLogonType, you need to use Logon32_logon_new_credentials to access remote resources,
To emulate a native user, use Logon32_logon_interactive.
2. There is a problem with the parameter format of the function.
A, for example
public static extern int LogonUser (String lpszusername, string lpszdomain, string lpszpassword, int dwLogonType, int dwlogonprovider, ref IntPtr phtoken);
In the lpszUserName, Lpszdomain, Lpszpassword will write clearly.
I've had problems here, the first time the test, the remote server is a separate file server, this is the way I call:
LogonUser ("MyName", "192.168.1.48", "Password", Logon32_logon_new_credentials,
Logon32_provider_default, ref token);
At the second test, the remote server is a member server in the domain mydomain that provides the file service. The code should then be:
LogonUser ("MyName", "MyDomain", "Password", Logon32_logon_new_credentials, Logon32_provider_default, ref token) ;
Note that the code is mydomain instead of an IP address.
B, again such as:
Refer to the above code
string remote = @ "\\192.168.1.48\generals"; String local = @ "P:"; String username = @ "domain\username"; string password = @ "password";
If @ "\\192.168.1.48\generals" becomes @ "\\192.168.1.48\generals\" will go wrong;
If the user is in the domain, then the @ "domain\username" becomes @ "UserName" error.