windows平台访问远程服务器共享目录下的access数据库文件
public class SharedDirectoryManager { // logon types private const int Logon32_Logon_Interactive = 2; private const int Logon32_Logon_Network = 3; private const int Logon32_Logon_New_Credentials = 9; // logon providers private const int Logon32_Provider_Default = 0; private const int Logon32_Provider_Winnt50 = 3; private const int Logon32_Provider_Winnt40 = 2; private const int Logon32_Provider_Winnt35 = 1; private WindowsImpersonationContext impersonationContext; [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] private 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)] private static extern int DuplicateToken(IntPtr hToken, int impersonationLevel, ref IntPtr hNewToken); [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern bool RevertToSelf(); [DllImport("kernel32.dll", CharSet = CharSet.Auto)] private static extern bool CloseHandle(IntPtr handle); public bool ImpersonateValidUser(string userName, string domain, string password) { var token = IntPtr.Zero; var 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) { var tempWindowsIdentity = new WindowsIdentity(tokenDuplicate); this.impersonationContext = tempWindowsIdentity.Impersonate(); if (this.impersonationContext != null) { AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal); CloseHandle(token); CloseHandle(tokenDuplicate); return true; } } } } if (token != IntPtr.Zero) CloseHandle(token); if (tokenDuplicate != IntPtr.Zero) CloseHandle(tokenDuplicate); return false; } public void UndoImpersonation() { this.impersonationContext.Undo(); } }
调ImpersonateValidUser成功后,按照本地目录可正常访问
如果是访问共享的access数据库文件
指定连接字符串:Provider=Microsoft.Jet.OLEDB.4.0;Data Source=\192.168.137.200ShareFolder est.mdb;OLE DB Services=-4;
为共享目录文件地址即可
如果不加OLE DB Services=-4;,可能会导致web中访问数据库时发生:
Microsoft.Jet.OLEDB.4.0 提供程序不支持 ITransactionLocal 接口。本地事务不可用于当前提供程序 的异常
跨平台(.net 5)共享目录访问解决方案
通过shell命令实现: net use \192.168.3.163software /User:administrator 123456 /PERSISTENT:YES
public class RemoteFileOperate { /// <summary> /// 远程访问目录 /// </summary> public string remotePath { get; set; } /// <summary> /// 用户名 /// </summary> public string userName { get; set; } /// <summary> /// 密码 /// </summary> public string passWord { get; set; } public RemoteFileOperate(string remotePath) { this.remotePath = remotePath; } public RemoteFileOperate(string remotePath, string userName, string passWord) { this.remotePath = remotePath; this.userName = userName; this.passWord = passWord; } /// <summary> /// 检测远程访问连接状态 /// </summary> /// <param name="path"></param> /// <param name="isNeedPersistent"></param> /// <returns></returns> public bool CheckConnectState() { bool Flag = false; Process proc = new 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 = string.Empty; string dosLineClean = @"net use * /del /y"; if (!string.IsNullOrEmpty(userName) || !string.IsNullOrEmpty(passWord)) { dosLine = @"net use " + remotePath + " /User:" + userName + " " + passWord + " /PERSISTENT:YES"; } else { dosLine = @"net use " + remotePath + " /PERSISTENT:NO"; } proc.StandardInput.WriteLine(dosLineClean); proc.StandardInput.WriteLine(dosLine); proc.StandardInput.WriteLine("exit"); while (!proc.HasExited) { proc.WaitForExit(1000); } string errormsg = proc.StandardError.ReadToEnd(); proc.StandardError.Close(); if (string.IsNullOrEmpty(errormsg)) { Flag = true; } } catch (Exception ex) { } finally { proc.Close(); proc.Dispose(); } return Flag; } }