如何在运行时要求用户提升权限?

| 某些由普通用户启动的应用程序在必要时会要求提升权限(例如,文件管理器需要编写此类文件夹),然后继续进行该操作。 如何复制这种行为?     
已邀请:
正如塔玛斯(Tamás)指出的那样,您需要启动具有更高权限的新流程。过去,我进行了很多搜索,但没有找到任何提高当前流程权利的方法。 假设您的主应用程序是App1.exe,然后调用需要提升权限的辅助进程App2.exe。 答:您可以将清单嵌入到App2.exe中,但更简单的方法是创建一个清单文件[文本文件],名称为App2.exe.manifest,其中包含以下内容,并将其放在与App2.exe相同的目录中。 注意: !!奇怪的是,如果您的应用程序名称不是App2.exe而是App2_install.exe或App2_setup.exe(即,如果应用程序名称包含\“ install \”或\“ setup \”),则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
    
仅在C#中需要时,请参阅此有关提升特权的问题;有关用户帐户控制的文章,请参见 概括起来:一个人需要以提升的权限启动一个新进程。高程级别无法在运行时更改。通过WinAPI或通过在可执行文件中嵌入正确的清单来完成具有较高权限的启动。     
简而言之:为Windows创建两个可执行文件。常规可执行文件,以及用于执行“提升的”操作(通过传递命令行选项)的辅助exe文件。 在第二个EXE文件中,添加带有
<requestExecutionLevel level=\"requireAdministrator\"/>
节点的应用程序清单文件。 启动工作程序应用程序时,请确保使用包装ShellExecute的QT函数,而不是使用CreateProcess,因为CreateProcess根本无法启动requireAdministrator应用程序,而ShellExecute(作为shell函数)可以执行UAC提升提示。 也可以使用ActiveX控件来执行此操作,但是由于您要定位Qt,因此似乎不太合适。     
您还可以在提升模式下启动COM对象。有关更多信息,请参见此MSDN文章。     

要回复问题请先登录注册