2011-05-24 44 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