如何在运行时向用户请求提升的权限
How can I ask the user for elevated permissions at runtime?
一些由普通用户启动的应用程序会在必要时请求提升权限(例如,文件管理器需要写入这样的文件夹),然后继续操作。
我如何复制这种行为?
正如Tamás所指出的,您需要启动一个具有提升权限的新流程。我在过去搜索了很多,但没有找到任何方法来提升当前程序的权利。
假设您的主应用程序是App1.exe,然后您调用需要提升权限的辅助进程App2.exe。
A。您可以在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创建两个可执行文件。常规可执行文件和用于执行"提升"操作(通过传递命令行选项)的worker exe文件。
在第二个EXE文件中添加一个带有<requestExecutionLevel level="requireAdministrator"/>
节点的应用程序清单文件。
启动辅助应用程序时,请确保使用包装ShellExecute的QT函数,而不是CreateProcess,因为CreateProcess无法启动所需的管理员应用程序,而ShellExecute[作为shell函数]可以执行UAC提升提示。
使用ActiveX控件也可以这样做,但由于您的目标是Qt,这似乎不太合适。
您还可以在提升模式下启动COM对象。有关详细信息,请参阅MSDN的这篇文章。
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 如何在boost beast http请求中设置http头
- 发送一个带有libcurl C++问题的帖子请求:s
- 在多个核心中处理一个HTTP请求
- Termux权限被拒绝
- AWS Lambda C++运行时权限被拒绝
- 为什么 KMS drmModeSetCrtc() 在 X11 会话中运行时会失败并被拒绝权限?
- 错误:请求非类类型为"MULTIMEDIA_FILME [500]"的成员|
- 使用 Winsock2.h C++向不和谐 API 发送 HTTP 请求时出现问题
- 每个服务器请求的内存预算
- 编写一个函数来删除单链表中的节点(尾部除外),仅授予对该节点的访问权限
- 在没有管理员权限的情况下连接到同一网络中的命名管道
- std::getline没有在while循环中重新请求用户输入
- 为什么我在空指针错误(链表)中获取成员访问权限
- 如何在Qt中请求管理员权限?
- 在其他机器上运行请求管理员权限的EXE文件
- 如何在Linux上使用polkit请求串行端口权限
- 正在运行时请求管理员权限
- 如果在Windows 8上,C++请求管理权限
- 如何在运行时向用户请求提升的权限