I need to install different setups silently with administrator privileges. I have to hard code the privileges because the users don´t know username and password to install the setups themselfes.
I have tried two different approaches.
- ProcessStartInfo with UserName, Password and UseShellExecute = false.
User Impersonation with
[DllImport("advapi32.dll", SetLastError = true)] private static extern bool LogonUser(...);
In both scenarios windowsPrincipal.IsInRole(WindowsBuiltInRole.Administrator)
returns false
and my setups do not run because of insufficient rights.
Strange behavior: LogonUser always returns true, even with invalid credentials.
Here is the impersonation class:
namespace BlackBlade.Utilities
{
/// <summary>
/// Quelle: http://www.blackbladeinc.com/en-us/community/blogs/archive/2009/08/10/runas-in-c.aspx
/// </summary>
public class SecurityUtilities
{
[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool LogonUser(string lpszUserName, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr phToken);
public delegate void RunAsDelegate();
public static void RunAs(RunAsDelegate methodToRunAs, string username, string password)
{
string userName;
string domain;
if (username.IndexOf('\\') > 0)
{
//a domain name was supplied
string[] usernameArray = username.Split('\\');
userName = usernameArray[1];
domain = usernameArray[0];
}
else
{
//there was no domain name supplied
userName = username;
domain = ".";
}
RunAs(methodToRunAs, userName, password, domain);
}
public static void RunAs(RunAsDelegate methodToRunAs, string username, string password, string domain)
{
IntPtr userToken;
WindowsIdentity adminIdentity = null;
WindowsImpersonationContext adminImpersonationContext = null;
try
{
if (LogonUser(username, string.IsNullOrEmpty(domain) ? "." : domain, password, 9, 0, out userToken))
{
//the impersonation suceeded
adminIdentity = new WindowsIdentity(userToken);
adminImpersonationContext = adminIdentity.Impersonate();
// todo: Entfernen.
WindowsPrincipal p = new WindowsPrincipal(adminIdentity);
MessageBox.Show(p.IsInRole(WindowsBuiltInRole.Administrator).ToString());
//run the delegate method
//methodToRunAs();
}
else
throw new Exception(string.Format("Could not impersonate user {0} in domain {1} with the specified password.", username, domain));
}
catch (Exception se)
{
int ret = Marshal.GetLastWin32Error();
if (adminImpersonationContext != null)
adminImpersonationContext.Undo();
throw new Exception("Error code: " + ret.ToString(), se);
}
finally
{
//revert to self
if (adminImpersonationContext != null)
adminImpersonationContext.Undo();
}
}
}
}