给Qt程序添加管理员权限总结(一定有你没见过的方式)

当我们写了一个Qt程序,程序会在C盘某些目录下创建文件时,会发现代码没有问题,但是就是创建失败。而当我们对程序右键,以管理员权限运行时,又可以正常创建文件。

此时,说明我们的程序默认不具备管理员权限,故而无法对某些目录进行写入。

根据我们的编译器不同,有如下2种情况。

一、使用MSVC编译器

在pro文件中,添加如下一行:

QMAKE_LFLAGS += /MANIFESTUAC:\"level=\'requireAdministrator\' uiAccess=\'false\'\"

重新编译之后,程序会带个盾牌标志。

在这里插入图片描述

但是会有个后遗症,会发现我们在debug下,无法进行调试了,会弹出"The CDB process terminated"的错误:

在这里插入图片描述

这是因为我们的QtCreator没有以管理员权限运行,却对管理员权限的程序进行调试,所以报错,具体为什么,我也不知道。

当重新以管理员权限运行QtCreator,并进行调试,就不会报错了。

然鹅,每次启动QtCreator都以管理员权限太麻烦,换作不清楚的人,启动这个工程,一定是一脸懵逼。

所以我们稍微修改下pro文件,让程序仅仅在release模式下,才以管理员权限运行。

CONFIG(release, debug|release){
QMAKE_LFLAGS += /MANIFESTUAC:\"level=\'requireAdministrator\' uiAccess=\'false\'\"
}

这样,debug就不受影响了。

二、使用MinGW编译器

1、创建文件uac.manifest

文件内容为:

<?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

加入如下内容:

1 24 uac.manifest

3、修改pro文件

.pro文件加入如下内容:

RC_FILE += res.rc

如果有其他ico等资源文件可以一起加入到res.rc文件中。

重新编译之后,程序会带个盾牌标志。

在这里插入图片描述

也会有在第一章中提到的无法debug后遗症。

所以我们稍微修改下pro文件,让程序仅仅在release模式下,才以管理员权限运行。

CONFIG(release, debug|release){
RC_FILE += res.rc
}

这样,debug就不受影响了。

三、使用代码实现以管理员权限运行程序

以上2种方式,比较常见。而且编译完之后,exe会带盾牌标志。

下面介绍一种,编译完不带盾牌,但是依然以管理员权限运行程序的方式。

我们首先创建UAC.h,如下:

#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类,如下:

#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文件中,存在如下原版代码,我的代码在此基础上,进行了一点修改,方便调用。

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;
		}
	}

    // ......
}

感兴趣,可以自己去看看。



若对你有帮助,欢迎点赞、收藏、评论,你的支持就是我的最大动力!!!

同时,阿超为大家准备了丰富的学习资料,欢迎关注公众号“超哥学编程”,即可领取。

本文涉及工程代码,公众号回复:53UACCode,即可下载。

在这里插入图片描述

  • 19
    点赞
  • 112
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 14
    评论
在 Windows 操作系统中,可以使用以下方法以管理员权限运行 Qt 程序: 1. 手动以管理员身份运行 Qt 应用程序 可以通过右键单击 Qt 应用程序的可执行文件或快捷方式,然后选择“以管理员身份运行”来手动以管理员身份运行 Qt 应用程序。 2. 使用 Qt Creator 设置管理员权限Qt Creator 中,可以通过在项目的“构建和运行”设置中选择“以管理员身份运行”选项来设置 Qt 应用程序管理员权限运行。 3. 使用 C++ 代码设置管理员权限 可以在 C++ 代码中使用 Windows API 函数来设置 Qt 应用程序管理员权限运行。例如,可以使用以下代码来获取当前进程的句柄并以管理员权限运行: ``` #include <Windows.h> int main(int argc, char *argv[]) { // 获取当前进程句柄 HANDLE hProcess = GetCurrentProcess(); // 以管理员权限运行 if (!OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES, &hToken)) { // 处理错误 return 1; } TOKEN_PRIVILEGES tp; ZeroMemory(&tp, sizeof(tp)); tp.PrivilegeCount = 1; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid)) { // 处理错误 return 1; } if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL)) { // 处理错误 return 1; } // 运行 Qt 应用程序 QApplication a(argc, argv); // ... return a.exec(); } ``` 以上是一些常用的方法,你可以根据具体情况选择合适的方法来以管理员权限运行 Qt 程序

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

百里杨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值