【问题标题】:How to request admin rights in Qt?如何在 Qt 中请求管理员权限?
【发布时间】:2018-06-22 05:04:29
【问题描述】:

我尝试在 Windows 注册表中创建一个键,但出现此错误:

5 访问被拒绝。

sn-p的代码是这样的:

HKEY hKey;
LPCTSTR sk = TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\notepad.exe"); //notepad.exe is the key I want to create
    //note: if I change the first parameter to KEY_CURRENT_USER, the key will be created 
LONG createResKey = RegCreateKeyEx(HKEY_LOCAL_MACHINE, sk, 0, NULL, REG_OPTION_BACKUP_RESTORE, KEY_ALL_ACCESS, NULL, &hKey, NULL);

if (createResKey == ERROR_SUCCESS) {
    qDebug() << "Success creating key.";
}
else {
    qDebug() << "Error creating key.";

    showErrorText(createResKey);
}

也许是因为我的程序没有管理员权限,我尽力在网上做研究并试图获得管理员权限,但失败了。我现在很困惑如何解决这个问题。

编辑:我想要实现什么?
我试图通过修改注册表来阻止某些特定的应用程序启动。例如,如果我想阻止记事本,首先我必须创建一个“notepad.exe”键,然后为其设置一个字符串值“debugger”并将其值设置为“debugfile.exe”。所以记事本将被阻止启动。

【问题讨论】:

  • 您是否考虑在资源管理器中右键单击 EXE 并选择“以管理员身份运行”?
  • @selbie 是的,我确实尝试过,但不知何故它仍然说“访问被拒绝”。此外,我希望它以编程方式获得管理员权限
  • 您确定需要管理员权限吗?你不能避开他们吗?然后生活会更轻松(因为您只需在操作系统轻松提供的内容上构建)
  • @BasileStarynkevitch 实际上不太确定。我只需要弄清楚为什么它说“访问被拒绝”。但从网上查到,有人说可能是我没有管理员权限。
  • 这两个答案在技术上似乎都是正确的,但你到底想在这里做什么?最终目标是什么?

标签: c++ windows qt qt5


【解决方案1】:

GUI 工具包非常复杂,因此通常建议避免使用管理权限来运行它们,并且许多 GUI 工具包(出于充分的理由)具有检测和禁用(或警告)它的代码。在 Linux 上,这意味着您不应该以 root 身份运行 GTK 或 Qt 代码(如果这样做,会发出一些警告,或者工具包可能会中止;对于 Qt,请参阅 this;对于 GTK,请参阅 that)。

在实践中,您应该尝试让一些具有管理权限的小型程序(可能在命令行上,或作为守护程序)并让您的 Qt 程序启动它(例如使用QProcess)和/或与它通信(使用某种inter-process communication),利用operating system 提供的process isolation 和multi-user 功能。

我想对操作系统的一些一般理解应该会有所帮助。然后我建议阅读Operating Systems: Three Easy Pieces 以更深入地了解操作系统。

详细信息-即如何以比您的 Qt 程序更多的权限启动某些程序 - 是特定于操作系统的(在 Linux 上,请阅读 setuid)。进程间通信设施也是特定于操作系统的(在 Linux 上,请参阅pipe(7)、fifo(7)、shm_overview(7)、unix(7)、sem_overview(7) 等...并阅读一些 Linux 编程书籍,也许是旧的ALP或更新的东西)。如何在 Windows 上获得更多权限或进行进程间通信是一个非常不同的问题(与 Qt 无关)。

因此,您需要深入了解WinAPI 文档(可能是here),以了解如何启动具有管理权限的守护进程或小程序以及如何与其执行进程间通信。我猜想 Windows 有这样的设施,但它们没有包含在 Qt 中(也没有对注册表的访问),您需要编写 Windows 特定代码并了解有关 WinAPI 的更多信息。我无法帮助你,因为我不知道也从未使用过 Windows。

【讨论】:

  • 感谢您的建议,虽然您所说的目前我无法理解,但我会尽力调查。
  • 你可能需要花几个月的时间来学习 Windows 编程。
  • @BasileStarynkevitch,“GUI 工具包非常复杂,通常建议避免使用管理权限来运行它们”。我知道很多 GUI 程序(至少在 Windows 上)在执行某些功能时要求管理权限。请您详细说明为什么这被认为是不好的做法?这里的目的是避免这些 GUI 工具包中可能存在的漏洞接管整个系统(并将它们限制为用户权限)吗?我认为 docker 是使用您建议的架构的软件示例......谢谢......
  • AFAIK,GTK 和 Qt 代码在 Linux 上都有一些规定(例如发出至少一些警告)以避免以 root 身份运行
【解决方案2】:

KEY_ALL_ACCESS 是一个相当重量级的权限。即使是升级的进程也可能无法访问 HKLM 中的系统注册表项。在任何情况下都不要使用REG_OPTION_BACKUP_RESTORE 和KEY_ALL_ACCESS 标志。相反,只需请求 KEY_WRITE。

LONG createResKey = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
                                    sk,
                                    0,
                                    NULL,
                                    0,
                                    KEY_WRITE,  
                                    NULL, 
                                    &hKey,
                                    NULL);

然后右键单击您的 EXE 并选择“以管理员身份运行”。

【讨论】:

  • 刚刚尝试了您的解决方案,它奏效了。谢谢。但是有没有一种方法不需要手动点击以管理员身份运行,程序在运行时就获得了管理员权限?
  • 那不是很安全...如果任何程序都可以修改系统注册表。
  • @好的!再次感谢您的解决方案。它为我节省了大量时间来自己进行研究。
【解决方案3】:

要在运行时获得管理员权限,您需要添加到您的 .pro 文件中:

win32 {
    RC_FILE = rcfile.rc
}

然后使用以下内容创建 rcfile.rc:

#include <windows.h>
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "YourProgrammName.exe.manifest"

然后使用以下文本创建 YourProgrammName.exe.manifest 文件:

name="YourProgrammName.myapp" type="win32" />
<description> Really Cool App</description>
<dependency />
<!-- Identify the application security requirements. -->
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
  <security>
   <requestedPrivileges>
    <requestedExecutionLevel
      level="requireAdministrator"
      uiAccess="false"/>
    </requestedPrivileges>
   </security>
</trustInfo>
<!-- padding to four-byte multiple file size including the byte order mark --   
<!-- padding 123 -->
 </assembly>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-17
    • 2020-01-25
    • 2018-05-01
    • 2011-09-19
    相关资源
    最近更新 更多