公司產品在 Vista 系統下遇到一個棘手問題:Guest 使用者註冊 Flash.ocx 時會靜默失敗,卻不報任何錯誤;同樣操作在 Windows XP 下卻能成功。後來發現原來是 Guest 帳號權限不足,必須透過 UAC(使用者帳戶控制)彈出提權視窗輸入管理員密碼,才能獲得足夠權限完成註冊。
經過廣泛搜尋,網路上多以 Delphi 為例,VC++ 相關資料較少。最終歸納出兩種簡單有效的方法,能讓 VC++ 編譯的 EXE 在 Vista 下自動彈出 UAC 對話框:
Vista 內建「安裝程式偵測」機制,若執行檔名稱包含 update、install、setup 等敏感關鍵字,系統會自動判定為安裝程式並彈出 UAC。只需將輸出的 EXE 重新命名(例如 MyApp_Install.exe),即可無需修改程式碼即達到提權目的。
在專案資源中加入自訂 Manifest,明確宣告 requestedExecutionLevel 為 requireAdministrator,這是更標準、可控的做法。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
version="1.0.0.0"
processorArchitecture="X86"
name="MyApp.exe"
type="win32"
/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
24(即 RT_MANIFEST),ID 設為 1(對應 CREATEPROCESS_MANIFEST_RESOURCE_ID)。mt.exe 事後嵌入法若專案已編譯完成,也可用 Windows SDK 提供的 mt.exe 將 Manifest 嵌入既有 EXE:
mt.exe -manifest MyApp.exe.manifest -outputresource:MyApp.exe;1
採用 Manifest 方式符合 Microsoft 最佳實務,且不依賴檔名 heuristics,建議作為預設方案;檔名法可作為快速測試或臨時備援。兩種方法皆能解決 Vista Guest 帳號無法自動提權的問題,讓 OCX 註冊等需管理員權限的操作順利完成。