c++ - 我如何在运行时要求用户提升权限?

标签 c++ windows qt

一些由普通用户启动的应用程序会在必要时请求提升权限(例如,文件管理器需要写入此类文件夹),然后继续操作。

我怎样才能复制这种行为?

最佳答案

正如 Tamás 指出的那样,您需要启动一个具有更高权限的新流程。之前找了很多都没有找到给当前进程提权的方法。

假设您的主要应用程序是 App1.exe,然后您调用需要提升权限的辅助进程 App2.exe。


A.您可以在 App2.exe 中嵌入 list ,但更简单的方法是创建一个名为 App2.exe.manifest 的 list 文件 [文本文件],内容如下,并将其放在与 App2.exe 相同的目录中。 笔记: !!奇怪的是,如果您的应用程序名称不是 App2.exe,而是 App2_install.exe 或 App2_setup.exe(即,如果应用程序名称包含“install”或“setup”),Windows Vista/Windows 7 中将自动出现一个 UAC 对话框即使没有 list 文件也会要求提升权限!! 这是 list 文件的示例:

<?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 操作系统上使用 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++ - 我如何在运行时要求用户提升权限?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6108851/

相关文章:

r - download.file() 在 Windows 上生成 "invalid"zip 文件,但在 Mac 上工作正常

qt - CMake、Qt 和 CMAKE_INCLUDE_PATH

c++ - 尝试应用肖恩 parent 谈话中的模式 "inheritance is the base class of evil"

c++ - 如何通过 MessageBox 输出一个指针?

C++ 日期验证连续运行

c++ - QtPlugins 实现多个接口(interface)并转换为通用接口(interface)

ios - 无法在 QT 项目中添加 iOS OpenCV 框架

c++ - Boost库在ubuntu上产生错误

windows - 创建 Bat 文件以对文件夹中的所有文件执行命令

c++ - 在哪里可以找到可用的 winnt.h? Rubenvb 的似乎是非常错误的