之前已經學過幾種強制用管理者權限跑程式的方法,包含:在 EXE 內嵌 Manifest 指定 <requestedExecutionLevel level="requireAdministrator" />RunAs、檔案總管內容設定PowerShell 自動改用管理者權限執行... 等做法。這回需求又有點不同,我有個 .NET 6 Console 寫的 CLI 工具,計劃在 Cmd/Windows Terminal 帶入參數執行,若發現非管理者時希望做到「帶入目前輸入參數重新以管理者權限執行」。

展示如下。當使用一般使用者身分跑 ReqAdmin.exe arg1 arg2 arg3,系統將彈出 UAC 確認視窗,之後重新以管理者權限執行,並原封不動帶入 arg1 arg2 arg3 參數。

程式原理不難,由 WindowsIdentity 檢查目前角色是否為 Administrator,若不是就另開 Process,用 Process.GetCurrentProcess().MainModule!.FileName 取得執行檔路徑 (參考),輸入參數則以 Environment.GetCommandLineArgs() 取得字串陣列,略過第一個執行檔名稱,其餘剛好作為 StartInfo.Arguments 參數,Verb 則設為 "runas" 要求改用管理者執行,搞定。

using System.Diagnostics;
using System.Security.Principal;

var wp = new WindowsPrincipal(WindowsIdentity.GetCurrent());
if (wp == null || !wp.IsInRole(WindowsBuiltInRole.Administrator))
{
    //https://blog.darkthread.net/blog/net6-get-exe-path/
    var exeFileName = Process.GetCurrentProcess().MainModule!.FileName;
    var exeArgs = string.Join(" ", Environment.GetCommandLineArgs().Skip(1).ToArray());
    var proc = new Process
    {
        StartInfo = {
            FileName = exeFileName,
            Verb = "runas",
            UseShellExecute = true,
            Arguments = exeArgs
        }
    };
    proc.Start();
    return;
}
Console.WriteLine($"args = {System.Text.Json.JsonSerializer.Serialize(args)}");
Console.Write("Press enter to exit...");
Console.ReadLine();

Example of restart .NET application as administrator.


Comments

Be the first to post a comment

Post a comment