Vista/Windows 7 引入 UAC(使用者帳戶控制),即使以管理員登入,應用程式預設也無法寫入系統目錄、登錄表等敏感區域。需讓程式啟動時提示使用者提權。
requestedExecutionLevel 節點:<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" ...>
<assemblyIdentity version="1.0.0.0" name="MyApplication.app" />
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<!-- 選項說明:
asInvoker - 以目前權限執行(預設)
requireAdministrator - 僅以系統管理員權限執行
highestAvailable - 以目前使用者可取得的最高權限執行
-->
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
</asmv1:assembly>
| 層級 | 行為 |
|---|---|
| asInvoker | 以目前使用者權限執行,不提權。 |
| highestAvailable | 以目前使用者可取得的最高權限執行。非管理員帳號登入時仍可執行,但僅具一般權限。 |
| requireAdministrator | 強制要求系統管理員權限。非管理員帳號登入時程式無法啟動。 |
若希望非管理員帳號也能執行(功能受限),建議用 highestAvailable;必須管理員權限才用 requireAdministrator。
權威文件:Create and Embed an Application Manifest (UAC)
public static bool IsAdministrator() {
WindowsIdentity identity = WindowsIdentity.GetCurrent();
WindowsPrincipal principal = new WindowsPrincipal(identity);
return principal.IsInRole(WindowsBuiltInRole.Administrator);
}
設定 asInvoker 時回傳 false;設定 requireAdministrator 回傳 true。
在 Program.cs 的 Main 方法中加入判斷邏輯:
static void Main(string[] Args) {
System.Security.Principal.WindowsIdentity identity = System.Security.Principal.WindowsIdentity.GetCurrent();
Application.EnableVisualStyles();
System.Security.Principal.WindowsPrincipal principal = new System.Security.Principal.WindowsPrincipal(identity);
if (principal.IsInRole(System.Security.Principal.WindowsBuiltInRole.Administrator)) {
Application.Run(new Form1());
}
else {
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.FileName = System.Windows.Forms.Application.ExecutablePath;
startInfo.Arguments = String.Join(" ", Args);
startInfo.Verb = "runas"; // 關鍵:要求以管理員身分執行
System.Diagnostics.Process.Start(startInfo);
System.Windows.Forms.Application.Exit();
}
}
原理:若非管理員,建立新行程並設 Verb = "runas" 觸發 UAC 提示,使用者確認後以管理員權限啟動新執行個體,原執行個體退出。