Windows Vista 引入使用者帳戶控制 (UAC),限制標準使用者修改系統設定。Delphi 應用程式若需寫入 HKLM、Program Files、系統目錄等受保護位置,必須在 Manifest 中宣告 requireAdministrator,讓系統在啟動時彈出 UAC 提示並顯示盾牌圖示。本文說明手動嵌入 Manifest 的完整步驟。
建立 UAC.manifest (UTF-8 編碼):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- Windows 10/11 相容性宣告 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" /> <!-- Win 10 -->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" /> <!-- Win 8.1 -->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" /> <!-- Win 8 -->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" /> <!-- Win 7 -->
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" /> <!-- Vista -->
</application>
</compatibility>
</assembly>
| 屬性 | 可用值 | 用途 |
|---|---|---|
level | asInvoker (預設)、highestAvailable、requireAdministrator | 權限需求層級 |
uiAccess | true/false | 是否需繞過 UIPI (螢幕閱讀器等特殊用途),通常 false |
UAC.rc1 24 "UAC.manifest"
1:資源 ID24:資源類型 RT_MANIFEST (系統常數)UAC.manifest:Manifest 檔案路徑"C:\Program Files (x86)\Embarcadero\Studio\22.0\bin\brcc32.exe" UAC.rc -foUAC.res
路徑依 Delphi 版本調整,通常在 Bin 目錄下。
program MyApp;
uses
Forms,
MainUnit in 'MainUnit.pas' {MainForm};
{$R *.res}
{$R UAC.res} // 關鍵:嵌入 Manifest 資源
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TMainForm, MainForm);
Application.Run;
end.
MyApp.exeuses ShellApi, ShlObj;
function IsRunAsAdmin: Boolean;
var
Token: THandle;
Elevation: TOKEN_ELEVATION;
ReturnLength: DWORD;
begin
Result := False;
if OpenProcessToken(GetCurrentProcess, TOKEN_QUERY, Token) then
try
if GetTokenInformation(Token, TokenElevation, @Elevation, SizeOf(Elevation), ReturnLength) then
Result := Elevation.TokenIsElevated <> 0;
finally
CloseHandle(Token);
end;
end;
// 使用範例
if not IsRunAsAdmin then
begin
// 重新啟動自身並請求提權 (ShellExecute "runas")
ShellExecute(Handle, 'runas', ParamStr(0), '', nil, SW_SHOWNORMAL);
Application.Terminate;
end;
| 現象 | 原因 | 解決 |
|---|---|---|
| 無盾牌圖示 | Manifest 未正確嵌入 | 用 Resource Hacker 開啟 EXE 檢查 RT_MANIFEST 資源是否存在 |
| 雙擊無 UAC 提示 | level="asInvoker" 或缺少 trustInfo 區段 | 確認 Manifest XML 結構正確、level="requireAdministrator" |
| 每次執行都跳 UAC | 正常行為,requireAdministrator 會每次提示 | 若需自動提權,改用排程工作或服務模式 |
| IDE 執行不提權 | IDE 本身未提權 | 以管理員身分執行 IDE,或使用外部除錯 |
專案選項 → Application → Manifest File → 勾選 Enable Manifest → 選擇 Level: requireAdministrator。IDE 會自動產生並嵌入 Manifest,無需手動 RC/RES 步驟。
嵌入 requireAdministrator Manifest 是 Delphi 應用程式相容 Vista+ UAC 的標準做法。雖然會讓使用者每次啟動見到提示,但能確保寫入系統區域的操作不會靜默失敗。對於僅偶爾需管理員權限的操作,建議採用「主程式標準權限 + 獨立提權輔助程式」架構,平衡使用者體驗與安全性。