由于某项目中课件资源过多,资源文件的存储采用了分布式文件系统,但是在局域网中如何访问又面临着一个问题,即局域网中访问各主机的文件同访问本机盘符下的文件是不同的,本人通过网上查询各种方案的对比,并且在实际项目中应用后对各种局域网文件访问的方法作了完整的总结
1 调用Net use DOS命令
///
/// 1.远程操作工具类
///
public class RemoteFileTools
{
///
/// 调用Net use命令,实现远程文件操作
///
///
///
///
///
///
/// 使用方法:
/// if (Connect("192.168.1.48", "用户名", "密码"))
/// {File.Copy(@"\\192.168.1.48\共享目录\test.txt", @"e:\\test.txt", true);}
///
public static bool Connect(string remoteHost, string userName, string passWord)
{
bool Flag = true;
System.Diagnostics.Process proc = new System.Diagnostics.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;
}
public static bool Ping(string remoteHost)
{
bool Flag = false;
System.Diagnostics.Process proc = new System.Diagnostics.Process();
try
{
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; proc.Start();
string dosLine = @"ping -n 1 " + remoteHost; proc.StandardInput.WriteLine(dosLine);
proc.StandardInput.WriteLine("exit"); while (!proc.HasExited)
{
proc.WaitForExit(500);
}
string pingResult = proc.StandardOutput.ReadToEnd(); if (pingResult.IndexOf("(0% loss)") != -1)
{
Flag = true;
}
proc.StandardOutput.Close();
}
catch (Exception ex) { }
finally
{
proc.Close(); proc.Dispose();
}
return Flag;
}
}
2 同上面方法有些相似之处,映射远程资源,然后访问
///
/// 2. 调用WNetAddConnection2、WNetAddConnection3或者NetUseAdd函数,进行磁盘映射
///
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的格式一定要正确,否则可能出现错误
string remote = @"\\192.168.193.90\dir";
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);
}
}
}
///
/// 3. 使用WebClient类实现
///
public class WebClint
{
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)
{
// 如果网络很慢,而文件又很大,这时可能有超时异常(Time out)。
}
}
public void Test()
{
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)
{
// 如果网络很慢,而文件又很大,这时可能有超时异常(Time out)。
}
}
}
///
/// 1.局域网内跨主机远程文件访问类,实现模拟登录,获取凭证后即可同本机路径一样访问
///
///
/// invoke demo,详见方法中的TestFunc:
/// RemoteFileHelper rm = new RemoteFileHelper();
/// if (rm.impersonateValidUser("administrator", "\\192.168.193.50", "******"))
/// {System.IO.File.Copy(@"\\192.168.193.50\123\platV0.1.zip", @"E:\\f1\\platV0.1.zip", true);
/// System.IO.File.Copy(@"E:\\f1\\platV0.1.zip",@"\\192.168.193.50\123\platV0.2.zip", true);}
///
public class RemoteFileHelper
{
// 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;
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来访问远程资源。
// 如果要(通过模拟用户获得权限)实现服务器程序,访问本地授权数据库可
// 以用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)
{
System.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;
}
public void undoImpersonation()
{
impersonationContext.Undo();
}
public void Test()
{
bool isImpersonated = false;
try
{
if (impersonateValidUser("UserName", "Domain", "Password"))
{
isImpersonated = true;
File.Copy(@"\\192.168.1.48\generals\now.htm", "c:\\now.htm", true);
}
}
finally
{
if (isImpersonated)
undoImpersonation();
}
}
}