C # Multiple ways to access remote host resources share

Source: Internet
Author: User
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.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.