使用LocalSystem运行的服务不能访问共享文件夹,即使共享文件夹权限是对“EveryOne”可读写也不行,目前使用过两种方式,但都需要设置用户密码。
1、使用用户名加密码的方式运行服务。
将 ProjectInstaller 的 Account设置为User
然后打开 ProjectInstaller 的设计器代码
在 InitializeComponent 中设置 ProjectInstaller的Username和Password。运行服务时会直接以设置的用户名运行,可以直接访问该用户名可访问的所有位置。
2、通过API模拟用户登录,感觉比较灵活,可以在服务中随时切换到不同用户权限,服务的运行权限为LocalSystem。
public static class LogonNet { const int LOGON32_LOGON_INTERACTIVE = 2; const int LOGON32_LOGON_NETWORK = 3; const int LOGON32_LOGON_NEW_CREDENTIALS = 9; 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 static WindowsImpersonationContext impersonationContext; public static bool impersonateValidUser(String userName, String domain, String password) { WindowsIdentity tempWindowsIdentity; IntPtr token = IntPtr.Zero; IntPtr tokenDuplicate = IntPtr.Zero; if (RevertToSelf()) { 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 static void undoImpersonation() { impersonationContext.Undo(); } }
调用方式
private void test() { if (LogonNet.impersonateValidUser("userTest", "Users", "userPassword")) { using (StreamWriter writer=new StreamWriter("\\192.168.1.13\\ShareTest\\test.txt")) { writer.WriteLine("模拟登录访问网络共享文件成功"); } } }
感觉第二种方式更灵活一点,先这样用了