0

管理者権限でさまざまなセットアップをサイレント インストールする必要があります。ユーザーは自分でセットアップをインストールするためのユーザー名とパスワードを知らないため、特権をハードコーディングする必要があります。

私は2つの異なるアプローチを試みました。

  1. UserName、Password、および UseShellExecute = false の ProcessStartInfo。
  2. ユーザーのなりすまし

    [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();
            }
        }
    }
}
4

3 に答える 3

3

RunAsで開始するプロセスにマニフェストを追加して、昇格を要求します。

編集:まず、LogonUser / CreateProcessAsUserまたはCreateProcessWithLogonのいずれかを使用して、既知の管理者クレデンシャルを使用してプロセスを開始します。次に、実際の管理者権限を確認し(UACがオフになっている可能性があります)、必要に応じて、このプロセス(昇格されていない管理者として実行)に、runas動詞を使用してShellExecuteExで自身の別のコピーを開始させます。これが唯一の方法です。UACは、ユーザーの確認なしに昇格を禁止するように明示的に設計されています。

UACがオフになっていない限り、ユーザーは標高を確認する必要があります。ユーザーエクスペリエンスを向上させるために(怖くないメッセージボックス)、コード署名証明書を取得して、この実行可能ファイルに署名します。

于 2012-06-28T11:26:26.460 に答える
0

グループポリシーを使用して、MSIまたはEXEインストーラーを展開します。

または、タスクスケジューラを使用して、ローカルシステムアカウントとしてインストーラーを実行します。

于 2012-06-28T09:04:18.663 に答える
0

dwLogonType を 9 ではなく 2 に設定してみましたか?

http://msdn.microsoft.com/en-us/library/windows/desktop/bb540756(v=vs.85).aspx

これは私のために働くコードサンプルです:

    public const int LOGON32_LOGON_INTERACTIVE = 2;
    public const int LOGON32_PROVIDER_DEFAULT = 0;

    WindowsImpersonationContext impersonationContext;

    [DllImport("advapi32.dll")]
    public static extern int LogonUserA(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);

        WindowsIdentity tempWindowsIdentity;
        IntPtr token = IntPtr.Zero;
        IntPtr tokenDuplicate = IntPtr.Zero;

        if (RevertToSelf())
        {
            if (LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE,
                LOGON32_PROVIDER_DEFAULT, ref token) != 0)
            {
                if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
                {
                    tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
                    impersonationContext = tempWindowsIdentity.Impersonate();
                    if (impersonationContext != null)
                    {
                        CloseHandle(token);
                        CloseHandle(tokenDuplicate);
                        return true;
                    }
                }
            }
        }
        if (token != IntPtr.Zero)
            CloseHandle(token);
        if (tokenDuplicate != IntPtr.Zero)
            CloseHandle(tokenDuplicate);
于 2012-06-28T11:03:22.507 に答える