管理者権限でさまざまなセットアップをサイレント インストールする必要があります。ユーザーは自分でセットアップをインストールするためのユーザー名とパスワードを知らないため、特権をハードコーディングする必要があります。
私は2つの異なるアプローチを試みました。
- UserName、Password、および UseShellExecute = false の ProcessStartInfo。
ユーザーのなりすまし
[DllImport("advapi32.dll", SetLastError = true)] private static extern bool LogonUser(...);
どちらのシナリオでもwindowsPrincipal.IsInRole(WindowsBuiltInRole.Administrator)
false が返され、権限が不十分なためにセットアップが実行されません。
奇妙な動作: 資格情報が無効であっても、LogonUser は常に true を返します。
偽装クラスは次のとおりです。
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();
}
}
}
}