2011-05-24 84 views

回答

4

正如Tamás指出的那樣,您需要啓動一個提升權利的新流程。過去我搜查了很多,但我沒有找到任何提升當前流程權限的方法。

假設你的主應用程序是App1.exe,然後你調用一個輔助進程App2.exe,它需要提升權限。


答:您可以嵌入清單在App2.exe但更簡單的方法是創建一個清單文件[文本文件]命名App2.exe.manifest具有以下內容並把它放在與App2.exe相同的目錄。 注意:!!奇怪的是,如果您的應用程序的名稱不是App2.exe,而是App2_install.exe或App2_setup.exe(即,如果應用程序名稱包含「安裝」或「設置」),UAC對話框將自動出現在Windows Vista/Windows 7中並會要求提升權利,即使沒有清單文件! 這是清單文件的樣本:

<?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> 
</assembly> 

B.您可以使用類似的代碼在App1.exe以下啓動App2.exe

QString AppToExec = qApp->applicationDirPath() + "/App2.exe"; 
// Put any required parameters of App2.exe to AppParams string 
QString AppParams = ""; 
if (0 != genWin32ShellExecute(AppToExec, 
           "", // default verb: "open" or "exec" 
           AppParams, 
           false, // run hidden 
           true)) // wait to finish 
{ 
    // (...) handle error 
} 

。 ..最後,這是Win32函數genWin32ShellExecute的代碼()我創建了一個Win32 O/S使用QT時啓動一個進程或打開文檔:

部首:

#ifdef Q_OS_WIN // Implement genWin32ShellExecute() especially for UAC 
    #include "qt_windows.h" 
    #include "qwindowdefs_win.h" 
    #include <shellapi.h> 

int genWin32ShellExecute(QString AppFullPath, 
         QString Verb, 
         QString Params, 
         bool ShowAppWindow, 
         bool WaitToFinish); 
#endif 

CPP:

// Execute/Open the specified Application/Document with the given command 
// line Parameters 
// (if WaitToFinish == true, wait for the spawn process to finish) 
// 
// Verb parameter values: 
// ""   The degault verb for the associated AppFullPath 
// "edit"  Launches an editor and opens the document for editing. 
// "find"  Initiates a search starting from the specified directory. 
// "open"  Launches an application. If this file is not an executable file, its associated application is launched. 
// "print"  Prints the document file. 
// "properties" Displays the object's properties. 
// 
// Ret: 0 = success 
//  <0 = error 
#ifdef Q_OS_WIN 
int genWin32ShellExecute(QString AppFullPath, 
         QString Verb, 
         QString Params, 
         bool ShowAppWindow, 
         bool WaitToFinish) 
{ 
    int Result = 0; 

    // Setup the required structure 
    SHELLEXECUTEINFO ShExecInfo; 
    memset(&ShExecInfo, 0, sizeof(SHELLEXECUTEINFO)); 
    ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO); 
    ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS; 
    ShExecInfo.hwnd = NULL; 
    ShExecInfo.lpVerb = NULL; 
    if (Verb.length() > 0) 
     ShExecInfo.lpVerb = reinterpret_cast<const WCHAR *>(Verb.utf16()); 
    ShExecInfo.lpFile = NULL; 
    if (AppFullPath.length() > 0) 
     ShExecInfo.lpFile = reinterpret_cast<const WCHAR *>(AppFullPath.utf16()); 
    ShExecInfo.lpParameters = NULL; 
    if (Params.length() > 0) 
     ShExecInfo.lpParameters = reinterpret_cast<const WCHAR *>(Params.utf16()); 
    ShExecInfo.lpDirectory = NULL; 
    ShExecInfo.nShow = (ShowAppWindow ? SW_SHOW : SW_HIDE); 
    ShExecInfo.hInstApp = NULL; 

    // Spawn the process 
    if (ShellExecuteEx(&ShExecInfo) == FALSE) 
    { 
     Result = -1; // Failed to execute process 
    } else if (WaitToFinish) 
    { 
     WaitForSingleObject(ShExecInfo.hProcess, INFINITE); 
    } 

    return Result; 
} 
#endif 
+0

它實際上是我誰是我的研究後指出了這一點:P。感謝您的詳細解答。如果可執行文件名還包含字符串「update」,它也會觸發UAC。 – 2011-05-26 11:32:14

+0

我編輯了我的答案,並把你的名字寫在信用證上:-)我必須感謝你的提問並給我發表這段代碼的動機。我記得當我需要這個代碼時,我已經花費了至少1-2天,因爲在SO中沒有相應的問題。 – 2011-05-26 11:44:43

+0

謝謝你沒有必要:)。我非常感謝你花時間寫下這個詳細的答案,儘管這個問題已經有了一個可以接受的答案。 – 2011-05-26 12:24:02

2

簡而言之:爲Windows創建兩個可執行文件。常規可執行文件,以及用於執行「提升」操作(通過傳遞命令行選項)的worker exe文件。

爲第二個EXE文件添加一個應用程序清單文件,其中包含<requestExecutionLevel level="requireAdministrator"/>節點。

當啓動worker應用程序時,請確保使用包裝ShellExecute的QT函數,而不是CreateProcess,因爲CreateProcess只是無法啓動requireAdministrator應用程序,而ShellExecute(作爲shell函數)可以執行UAC提升提示。

也可以使用ActiveX控件來做到這一點,但是因爲你的目標是Qt,所以看起來不太合適。

2

您還可以在提升模式下啓動COM對象。有關更多信息,請參閱此MSDN article

相關問題