在 Windows NT/2000/XP 環境下,以特定使用者身分啟動程序是系統管理與自動化部署的常見需求。然而 LogonUser() API 要求呼叫者擁有「Act as part of the operating system」特權,一般管理員帳戶不具備。本文介紹一種巧妙的解決方案:將工具程式暫時安裝為系統服務,在 LocalSystem 權限下執行 LogonUser() 與 CreateProcessAsUser(),完成後自動卸載服務。
SE_TCB_PRIVILEGE 則啟動服務安裝流程CreateService() 安裝自身為服務,設定為 SERVICE_AUTO_START 或需求啟動ServiceMain() 中呼叫 LogonUser() 取得存取權杖CreateProcessAsUser() 啟動目標程序OpenSCManager()、CreateService()、StartService()、ControlService()、DeleteService()CreateFileMapping() + MapViewOfFile() 實現進程間資料交換
// 主程式進入點
int main(int argc, char* argv[])
{
if (!HasRequiredPrivilege()) {
InstallAndRunAsService(argc, argv); // 安裝服務、啟動、等待結果、清理
return 0;
}
// 已具備特權,直接執行
return RunAsUser(...);
}
// 服務主函數
void WINAPI ServiceMain(DWORD argc, LPTSTR* argv)
{
// 從共享記憶體讀取參數
// LogonUser() -> CreateProcessAsUser()
// 結果寫回共享記憶體
}
命令列直接執行程式名稱(無參數)即可顯示使用說明:
RunAsUser.exe
用法: RunAsUser.exe /user:Domain\User /password:Pwd /cmd:"Program.exe [args]"
隨附原始碼包含完整的:
這些組件可獨立重用於其他需要系統級權限操作的專案中。