QT中为程序加入超级管理员权限
- [Chapter1 QT中为程序加入超级管理员权限](#Chapter1 QT中为程序加入超级管理员权限)
-
- [1. mingw编译器](#1. mingw编译器)
- [2. MSVC编译器](#2. MSVC编译器)
- [3. CMAKE](#3. CMAKE)
- [Chapter2 如何给QT程序添加管理员权限(UAC)的几种方法](#Chapter2 如何给QT程序添加管理员权限(UAC)的几种方法)
-
- [1、Qt Creator中](#1、Qt Creator中)
- 2、vs中
- [Chapter3 Qt 程序添加管理员权限的几种方法](#Chapter3 Qt 程序添加管理员权限的几种方法)
- [Chapter4 QT编译出来的exe以管理员权限启动](#Chapter4 QT编译出来的exe以管理员权限启动)
- [Chapter5 给Qt程序添加管理员权限总结(一定有你没见过的方式)](#Chapter5 给Qt程序添加管理员权限总结(一定有你没见过的方式))
Chapter1 QT中为程序加入超级管理员权限
原文链接:https://blog.csdn.net/u013441358/article/details/127452147
QT的一些文件操作,注册表的操作等,有些操作会无效,主要是因为没有对C盘的相关权限。通过为程序加入超级管理员权限可以解决此问题。
1. mingw编译器
在pro工程文件中加入:
cpp
RC_FILE=main.rc
main.rc是Qt项目的资源文件,其内容示例如下:
cpp
IDI_ICON1 ICON DISCARDABLE "./res/logo.ico"
1 24 uac.manifest
第一行是为程序添加图标,第二行是增加超级管理员权限。
uac.manifest文件的内容示例如下:
cpp
<?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>
2. MSVC编译器
在QT工程文件中加入QMAKE_LFLAGS的增加配置:
cpp
QMAKE_LFLAGS += /MANIFESTUAC:\"level=\'requireAdministrator\' uiAccess=\'false\'\"
3. CMAKE
放在add_executable的后面:
cpp
set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS
"/MANIFESTUAC:\"level='requireAdministrator' uiAccess='false'\"
/SUBSYSTEM:WINDOWS")
已经获得windows管理员权限的应用程序图标上会出现一个盾牌,例如:
Chapter2 如何给QT程序添加管理员权限(UAC)的几种方法
原文链接:https://blog.csdn.net/A3872215/article/details/98039295
1、Qt Creator中
方案一:(仅适用于使用msvc编译器)
在PRO文件中添加一行指令即可,
cpp
QMAKE_LFLAGS += /MANIFESTUAC:\"level=\'requireAdministrator\' uiAccess=\'false\'\"
MANIFESTUAC内容如下:
cpp
<?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>
方案二:(适用于mingw32编译器)
先创建一个 .manifest 文件,如:app.manifest,文件内容如下:
cpp
<?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>
然后在exe所在的目录中执行mt指令(mt指令在VS自带的"开发人员命令提示"工具中)
bash
1 mt.exe -manifest "app.manifest" -outputresource:"app.exe";#1
注意:exe和manifest文件要在同一目录中。
以上就是让Qt程序以管理员权限运行的两种方法。
2、vs中
方案一:在你的工程右键属性,找到linker-->manifest file.之后设置UAC execution level为:requireAdmistrator.
Chapter3 Qt 程序添加管理员权限的几种方法
原文链接:https://blog.csdn.net/weixin_39568531/article/details/104825816
二、使用添加管理员权限的小工具
/// permission.bat
bash
start cmd /k " mt.exe -manifest "RunningPermission" -outputresource:"iphelper.exe";#1 &&taskkill /f /t /im cmd.exe"
Chapter4 QT编译出来的exe以管理员权限启动
原文链接:https://blog.csdn.net/weixin_44618297/article/details/125975286
1、编译QT时遇到问题:
2、解决方法
MinGW下加权限
这种方法需要先创建.manifest文件,如app.exe.manifest,文件内容如下:
cpp
<?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>
然后再创建一个.rc文件,如app.rc,这两个文件都需要放在Pro文件同级目录下,rc文件内容如下:
cpp
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "app.exe.manifest"
最后在Pro文件中再附加如下代码:
cpp
RC_FILE = app.rc
重新编译运行即可解决。
Chapter5 给Qt程序添加管理员权限总结(一定有你没见过的方式)
原文链接:https://blog.csdn.net/zyhse/article/details/108166181
当我们写了一个Qt程序,程序会在C盘某些目录下创建文件时,会发现代码没有问题,但是就是创建失败。而当我们对程序右键,以管理员权限运行时,又可以正常创建文件。
此时,说明我们的程序默认不具备管理员权限,故而无法对某些目录进行写入。
根据我们的编译器不同,有如下2种情况。
一、使用MSVC编译器
在pro文件中,添加如下一行:
cpp
QMAKE_LFLAGS += /MANIFESTUAC:\"level=\'requireAdministrator\' uiAccess=\'false\'\"
重新编译之后,程序会带个盾牌标志。
但是会有个后遗症,会发现我们在debug下,无法进行调试了,会弹出"The CDB process terminated"的错误:
这是因为我们的QtCreator没有以管理员权限运行,却对管理员权限的程序进行调试,所以报错,具体为什么,我也不知道。
当重新以管理员权限运行QtCreator,并进行调试,就不会报错了。
然鹅,每次启动QtCreator都以管理员权限太麻烦,换作不清楚的人,启动这个工程,一定是一脸懵逼。
所以我们稍微修改下pro文件,让程序仅仅在release模式下,才以管理员权限运行。
cpp
CONFIG(release, debug|release){
QMAKE_LFLAGS += /MANIFESTUAC:\"level=\'requireAdministrator\' uiAccess=\'false\'\"
}
这样,debug就不受影响了。
二、使用MinGW编译器
1、创建文件uac.manifest
文件内容为:
cpp
<?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>
2、创建资源文件res.rc
加入如下内容:
cpp
1 24 uac.manifest
3、修改pro文件
.pro文件加入如下内容:
cpp
RC_FILE += res.rc
如果有其他ico等资源文件可以一起加入到res.rc文件中。
重新编译之后,程序会带个盾牌标志。
也会有在第一章中提到的无法debug后遗症。
所以我们稍微修改下pro文件,让程序仅仅在release模式下,才以管理员权限运行。
cpp
CONFIG(release, debug|release){
RC_FILE += res.rc
}
这样,debug就不受影响了。
三、使用代码实现以管理员权限运行程序
以上2种方式,比较常见。而且编译完之后,exe会带盾牌标志。
下面介绍一种,编译完不带盾牌,但是依然以管理员权限运行程序的方式。
我们首先创建UAC.h,如下:
cpp
#ifndef UAC_H
#define UAC_H
#include <ShlObj_core.h>
#include <QCoreApplication>
// for IsUserAnAdmin()
#pragma comment (lib, "Shell32.lib")
class UAC
{
public:
// 以管理员权限启动一个新实例
// true-启动了新实例
// false-未启动新实例
static bool runAsAdmin()
{
if (IsUserAnAdmin())
{
return false; // 当前程序正以管理员权限运行
}
QStringList args = QCoreApplication::arguments(); // 获取命令行参数
if (args.count() < 2 || args[1] != "runas") // 不带参数或参数不为"runas"时,即直接运行
{
// 获取应用程序可执行文件的路径
QString filePath = QCoreApplication::applicationFilePath();
// 以管理员权限,执行exe程序
HINSTANCE ins = ShellExecuteA(nullptr, "runas", filePath.toStdString().c_str(),
"runas", nullptr, SW_SHOWNORMAL);
if (ins > (HINSTANCE)32)
{
return true; // 程序新实例启动成功
}
}
return false;
}
};
#endif // UAC_H
UAC类中只有一个方法runAsAdmin(),实现以管理员权限启动一个新实例程序。
当执行到ShellExecuteA()函数时,会请求以管理员权限启动一个新实例程序,如下:
点击"是",则表示允许启动,此时ShellExecuteA()返回值大于32;
点击"否",则表示禁止启动,此时ShellExecuteA()返回值小于32。
我们在main.cpp中调用UAC类,如下:
cpp
#include <QCoreApplication>
#include "UAC.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// 以管理员权限启动一个新实例
if (UAC::runAsAdmin())
{
return 0; // 启动成功,当前程序退出
} // 未启动,当前程序继续
return a.exec();
}
我们双击执行生成的exe时,首先就会请求以管理员运行一个新实例;
若允许了,那么当前程序就退出;
若不允许,则当前程序继续执行。
这样,实现了启动时选择权限,而后保留只有一个对应权限程序运行的效果,与上述2种方式,双击运行效果一致。
不同点: 由于使用启动一个外部进程的方式来实现,故生成的exe不会带盾牌标志。
后遗症: 也有一个问题,就是进行debug时,允许管理员权限运行,那么启动了新实例,而当前程序退出,所以是无法进行调试的。
只能选择禁止管理员权限运行,才能对当前程序进行调试。
小贴士:
我们发现很多大厂出品的软件,也具有管理员权限,但是人家exe是不带盾牌标志的。或许用户看到盾牌,会觉得这货不是个善类。。。所以还是尽量伪装一下,我们就是普通软件,真的人畜无害!!! (>‿◠)
这种方式就看大家的需要吧。
四、对第三章内容的补充
使用代码实现以管理员权限运行程序,思路是源自磁盘测试开源软件CrystalDiskMark,其github地址:https://github.com/hiyohiyo/CrystalDiskMark
在DiskMark.cpp文件中,存在如下原版代码,我的代码在此基础上,进行了一点修改,方便调用。
cpp
BOOL RunAsRestart()
{
int count;
#ifdef _UNICODE
TCHAR** cmd = ::CommandLineToArgvW(::GetCommandLine(), &count);
#else
TCHAR** cmd = ::__argv;
count = ::__argc;
#endif
if (count < 2 || _tcscmp(cmd[1], _T("runas")) != 0)
{
TCHAR path[MAX_PATH];
::GetModuleFileName(NULL, path, MAX_PATH);
if (::ShellExecute(NULL, _T("runas"), path, _T("runas"), NULL, SW_SHOWNORMAL)
> (HINSTANCE)32)
{
return TRUE;
}
}
return FALSE;
}
BOOL CDiskMarkApp::InitInstance()
{
// ......
if (! IsUserAnAdmin())
{
if (RunAsRestart())
{
return FALSE;
}
}
// ......
}
感兴趣,可以自己去看看。