Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Question
Tuesday, February 23, 2010 2:13 PM
I need to read some xml file in the remote PC's share folder by XmlReader of C#.
But the share folder have username and password.
what can I do?
pass the remote PC's username and password with the UNC for authenticate.
I have tryed the Win32API LogonUser with WindowsImpersonationContext of C#, but faild.
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
I set the parameter of LogonUser like this.
lpszUsername = Remote PC's username, like "guest"
lpszDomain = Remote PC's IP or HostName, like "172.25.73.116" or "Client2"
lpszPassword = the password of Remote PC's username
Is there Someone can tell me why access faild and how can I implement the request.
Thsnks a lots of.
All replies (12)
Tuesday, February 23, 2010 2:52 PM ✅Answered | 6 votes
I have this unc access class built into one of my common function libraries.
set the unc credentials with this
UNCAccess unc = new UNCAccess(@"\\host\share", "username", "domain", "password");
and here is the class
using System;
using System.Runtime.InteropServices;
using BOOL = System.Boolean;
using DWORD = System.UInt32;
using LPWSTR = System.String;
using NET_API_STATUS = System.UInt32;
namespace CommonFunctions
{
public class UNCAccess
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
internal struct USE_INFO_2
{
internal LPWSTR ui2_local;
internal LPWSTR ui2_remote;
internal LPWSTR ui2_password;
internal DWORD ui2_status;
internal DWORD ui2_asg_type;
internal DWORD ui2_refcount;
internal DWORD ui2_usecount;
internal LPWSTR ui2_username;
internal LPWSTR ui2_domainname;
}
[DllImport("NetApi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern NET_API_STATUS NetUseAdd(
LPWSTR UncServerName,
DWORD Level,
ref USE_INFO_2 Buf,
out DWORD ParmError);
[DllImport("NetApi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern NET_API_STATUS NetUseDel(
LPWSTR UncServerName,
LPWSTR UseName,
DWORD ForceCond);
private string sUNCPath;
private string sUser;
private string sPassword;
private string sDomain;
private int iLastError;
public UNCAccess()
{
}
public UNCAccess(string UNCPath, string User, string Domain, string Password)
{
login(UNCPath, User, Domain, Password);
}
public int LastError
{
get { return iLastError; }
}
/// <summary>
/// Connects to a UNC share folder with credentials
/// </summary>
/// <param name="UNCPath">UNC share path</param>
/// <param name="User">Username</param>
/// <param name="Domain">Domain</param>
/// <param name="Password">Password</param>
/// <returns>True if login was successful</returns>
public bool login(string UNCPath, string User, string Domain, string Password)
{
sUNCPath = UNCPath;
sUser = User;
sPassword = Password;
sDomain = Domain;
return NetUseWithCredentials();
}
private bool NetUseWithCredentials()
{
uint returncode;
try
{
USE_INFO_2 useinfo = new USE_INFO_2();
useinfo.ui2_remote = sUNCPath;
useinfo.ui2_username = sUser;
useinfo.ui2_domainname = sDomain;
useinfo.ui2_password = sPassword;
useinfo.ui2_asg_type = 0;
useinfo.ui2_usecount = 1;
uint paramErrorIndex;
returncode = NetUseAdd(null, 2, ref useinfo, out paramErrorIndex);
iLastError = (int)returncode;
return returncode == 0;
}
catch
{
iLastError = Marshal.GetLastWin32Error();
return false;
}
}
/// <summary>
/// Closes the UNC share
/// </summary>
/// <returns>True if closing was successful</returns>
public bool NetUseDelete()
{
uint returncode;
try
{
returncode = NetUseDel(null, sUNCPath, 2);
iLastError = (int)returncode;
return (returncode == 0);
}
catch
{
iLastError = Marshal.GetLastWin32Error();
return false;
}
}
}
}
Tuesday, February 23, 2010 2:19 PM
Mount it as a net drive using the "net use" command syntax from the command line. Use the Process class to run "net use". That's what I've done in the past, and it seems to work well.
Process p = Process.Start("net.exe", "use z: \computername\sharename password /USER:domainname\username");
p.WaitForExit();
// access the files as though they're on the Z drive.Coding Light - Illuminated Ideas and Algorithms in Software
Coding Light Wiki • LinkedIn • ForumsBrowser
Tuesday, February 23, 2010 2:25 PM
hello David.
Firstly, thanks for asking my question.
Our Customer not allow me to mount a net drive.
so, are there other solutions?
Thanks.
Tuesday, February 23, 2010 2:34 PM | 2 votes
The customer doesn't allow you to mount a net drive? Why not? It'll make your life 10x easier.
Okay, if they won't let you use a net drive... try simply using another syntax of net use:
Process p = Process.Start("net.exe", @"use \\computername\sharename password /USER:domainname\username");
p.WaitForExit();
// access the files as though they're on \computername\sharename.
File.Copy(@"\computername\sharename\somefile.txt," @"C:\temp\somefile.txt");
That should work just fine.Coding Light - Illuminated Ideas and Algorithms in Software
Coding Light Wiki • LinkedIn • ForumsBrowser
Wednesday, February 24, 2010 1:22 AM
Thanks
Wednesday, February 24, 2010 1:24 AM
hello BradMS
Thanks for your solution.
I tryed it and It works fine.
Tuesday, September 14, 2010 2:47 PM
Excellent sample!
Wednesday, December 1, 2010 12:29 AM
You made my day ! thank you so much for that solution, it is perfect for my need. I have been struggling for days.
Tuesday, September 27, 2011 1:14 PM
Thanks David.
Worked a treat for me, from a C# console app interfacing two samba mount point directories on network linux/unix servers.
Well, once I'd fixed my syntax error on the "net.exe use".
Wednesday, January 4, 2012 10:41 AM
well done thanx for this code...
Thursday, June 28, 2012 6:39 AM
Thank you, that's just what I needed.
Monday, December 7, 2015 5:15 PM
Thanks! This works great, but I'm curious about when to use the NetUseDelete() method? What is the best practice? In my case, I have a Winforms app with a form showing the user a list of documents (obtained from a database, not from the file share). When the user selects a document, the path to the file is dynamically constructed, and the file is opened with Process.Start. The file resides on a Samba share that has its own credentials. I can use your class to grant access to the share and open the document. But do I need to immediately call the NetUseDelete() method after opening the doc (these are read-only docs). Another thought was to instantiate your class with the credentials on Form Load, let the user browse multiple docs, and then call NetUseDelete() on Form Close. Your thoughts?
Thanks!