作为一个不同的用户启动.Net进程
我想启动一个具有pipe理员权限的进程。 当我运行下面的代码进程抱怨说它需要pipe理员权限:
public class ImpersonationHelper : IDisposable { IntPtr m_tokenHandle = new IntPtr(0); WindowsImpersonationContext m_impersonatedUser; #region Win32 API Declarations const int LOGON32_PROVIDER_DEFAULT = 0; const int LOGON32_LOGON_INTERACTIVE = 2; //This parameter causes LogonUser to create a primary token. [DllImport("advapi32.dll", SetLastError = true)] public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken); [DllImport("kernel32.dll", CharSet = CharSet.Auto)] public extern static bool CloseHandle(IntPtr handle); [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] public extern static bool DuplicateToken(IntPtr ExistingTokenHandle, int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle); #endregion /// <summary> /// Constructor. Impersonates the requested user. Impersonation lasts until /// the instance is disposed. /// </summary> public ImpersonationHelper(string domain, string user, string password) { // Call LogonUser to obtain a handle to an access token. bool returnValue = LogonUser(user, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref m_tokenHandle); if (false == returnValue) { int ret = Marshal.GetLastWin32Error(); throw new System.ComponentModel.Win32Exception(ret); } // Impersonate m_impersonatedUser = new WindowsIdentity(m_tokenHandle).Impersonate(); } #region IDisposable Pattern /// <summary> /// Revert to original user and cleanup. /// </summary> protected virtual void Dispose(bool disposing) { if (disposing) { // Revert to original user identity if (m_impersonatedUser != null) m_impersonatedUser.Undo(); } // Free the tokens. if (m_tokenHandle != IntPtr.Zero) CloseHandle(m_tokenHandle); } /// <summary> /// Explicit dispose. /// </summary> public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } /// <summary> /// Destructor /// </summary> ~ImpersonationHelper() { Dispose(false); } #endregion } using (new ImpersonationHelper("xxx.blabla.com", "xxxx", "xxxx")) { if (!string.IsNullOrEmpty(txtFilename.Text)) Process.Start(txtFilename.Text); }
你可以尝试这样的事情: 以另一个用户开始一个新的进程
代码示例:
System.Diagnostics.Process proc = new System.Diagnostics.Process(); System.Security.SecureString ssPwd = new System.Security.SecureString(); proc.StartInfo.UseShellExecute = false; proc.StartInfo.FileName = "filename"; proc.StartInfo.Arguments = "args..."; proc.StartInfo.Domain = "domainname"; proc.StartInfo.UserName = "username"; string password = "user entered password"; for (int x = 0; x < password.Length; x++) { ssPwd.AppendChar(password[x]); } passowrd = ""; proc.StartInfo.Password = ssPwd; proc.Start();
正确使用SecureString和一些附加function:
//You should use SecureString like the following SecureString password = new SecureString(); password.AppendChar('p'); password.AppendChar('a'); password.AppendChar('s'); password.AppendChar('s'); Process process = new Process(); process.StartInfo.UseShellExecute = false; //Set the working directory if you don't execute something like calc or iisreset but your own exe in which you want to access some files etc.. process.StartInfo.WorkingDirectory = "workingDirectory"; //Full path (eg it can be @"C:\Windows\System32\iisreset.exe" OR you can use only file name if the path is included in Environment Variables..) process.StartInfo.FileName = @"fileName"; process.StartInfo.Domain = "domain"; process.StartInfo.UserName = "userName"; process.StartInfo.Password = password; process.Start();
编辑:我不知道为什么这个答案被投票低于0,也许多一点解释是必要的。 如果您将在非交互式环境(如Web应用程序)中使用此方法,并且想要与用户一起运行一个进程,那么您可以使用一些选项来使用用户的密码。 您可以从存储器或代码中读取密码。 更好的方法; 你可以把它存储encryption。 但是,如果您打算以简单的forms使用它(也许暂时或只是为了testing某些东西等),则可以按照我所描述的方式使用SecureString
。 接受的答案不以正确的方式使用SecureString
。 从控制台读取密码到一个string,然后把它放到一个SecureString
是简单的错误。 被接受的答案并不能保证这个string或者某个东西,而只是欺骗它。 这是我添加这个答案的主要动机。 检查链接 。