在运行时请求管理员权限

Posted

技术标签:

【中文标题】在运行时请求管理员权限【英文标题】:Requesting administrator privileges at run time 【发布时间】:2011-09-19 02:44:02 【问题描述】:

是否可以让在 Windows 中运行的 C++ 应用程序在运行时向操作系统请求管理员权限?

我知道它可以在编译时完成,但似乎无法在任何地方找到它是否可以在运行时完成。

感谢您的帮助!

编辑:如果我希望当前实例具有提升的权限怎么办?例如,我可能有一些数据存储在我想保留的内存中。

【问题讨论】:

您可以使用runas 动词启动另一个进程。 根据编辑:看起来您需要序列化程序状态,以便您可以将其读回新进程。 另一种选择——让应用程序在特殊模式下可启动,它只是作为执行需要提升权限的任务的一种手段,使用 IPC 来传递数据——这将有一个很好的好处重新启动应用程序(保留 UI 上下文)——UAC 窗口将显示相同的应用程序名称(给人一种特权在运行时升级的完整错觉:)) 编译时怎么做? @MDXF ***.com/a/19617989/1422096 【参考方案1】:

如果您希望应用程序始终提升,您可以给它一个清单,方法是在内部构建一个(不是从技术上编译)或将一个外部清单放在与 exe 相同的文件夹中。如果您想决定以个人身份运行它,请右键单击 exe 或快捷方式,然后选择以管理员身份运行。如果您从代码启动它,那么作为@vcsjones cmets,您在启动该进程时使用runas 动词。例如:

ShellExecute( NULL, 
    "runas",  
    "c:\\windows\\notepad.exe",  
    " c:\\temp\\report.txt",     
    NULL,                        // default dir 
    SW_SHOWNORMAL  
); 

【讨论】:

+1。您可以使用 runas 作为管理员生成应用程序的第二个副本,然后让原始副本自行终止。 它对我不起作用 :( 可能是 CPP 版本问题?你能告诉我你用的是哪个 CPP 吗? 我可以确认这个“不起作用”。 ShellExecute 返回零,但 GetLastError() 给出 5 == ACCESS_DENIED。在我去问我自己的问题之前,我会进一步调查,但我认为你应该知道...... (实际上,runas 和管理员权限是一个红鲱鱼。无论如何我都会遇到这个问题,即使我以管理员身份运行调用应用程序 - 所以在注销此方法之前我还有另一个问题要解决) 让应用程序使用ShellExecute/Ex(runas) 运行自身的第二个副本对我来说一直很好。【参考方案2】:

不完全是,但你可以做相反的事情——如果你已经拥有这些权限,你可以放弃这些权限。因此,您可以使用Kate Gregory 列出的方法之一让您的程序以管理员身份开始运行。然后,放弃你不需要的特权;请参阅Dropping privileges in C++ on Windows 了解如何执行此操作。

【讨论】:

有没有办法删除权限,以便用户在应用程序运行时不会收到 UAC 提示? (然后在稍后重新获得权限,此时用户将收到 UAC 提示) @JonaGik 避免 UAC 提示,不要开始运行提升。根据请求启动另一个提升的应用(对您的应用进行分区),或者启动提升的同一应用的另一个副本并关闭第一个,再次根据请求。 我知道它是 POSSIBLE,但我不知道如何提升权限... Windows 7 taskmanager (taskmgr.exe) 可以在运行时做到这一点。内部如何?我不知道。以非管理员身份打开 taskmgr.exe,然后转到进程选项卡并按“显示所有用户的进程”按钮,然后它将在运行时请求管理员访问权限。 @hanshenrik 我知道为时已晚,但其他人可能会发现它很有用:Windows 7 中的任务管理器不会在运行时提升,因为这是不可能的。当您单击“显示所有用户的进程”时,它所做的只是重新启动自身提升。如果您在任务管理器中显示 PID 列,您将在taskmgr.exe PID 升高后更改。这里的神奇之处在于,您不会看到 Microsoft 对已知应用程序的提升请求,它是在 Windows 7 中实现的,与 Windows Vista 相比,它减少了提升请求的数量。 :) 这听起来像是“我们没有卫生纸,但我们有砂纸”——我深表歉意,我无意冒犯任何人。据我了解,我们的目标是尽可能避免使用 UAC。如果我们一开始就调用 UAC,就达不到目的了。【参考方案3】:

您只能在创建过程中提升进程。当进程已经运行时,无法更改其安全令牌:它要么运行提升,要么不运行。

如果您的应用程序需要执行管理任务,并且它通常以非提升的方式运行,您必须创建另一个 .exe,该 exe 将通过其清单请求提升。要启动提升的进程,您必须使用 ShellExecuteShellExecuteEx 函数。从您的主进程中,您将需要一种方法将命令传递给将运行提升的新进程。


有关 UAC 的更多信息,请阅读Designing UAC Applications for Windows Vista 系列。

【讨论】:

【参考方案4】:

按照此处所述将清单文件添加到您的 EXE 中。

http://msdn.microsoft.com/en-us/library/bb756929.aspx

【讨论】:

【参考方案5】:

您的进程(和线程)具有分配给它们的令牌。该令牌已经设置了您的所有组。在 UAC 下,管理员组被禁用。 UAC 将删除该禁用组,以便您最终获得完整的管理员令牌。

要达到同样的效果,您必须拥有 TCB 特权。换句话说,要在运行时提升进程,您将需要在 SYSTEM 帐户下运行的进程的帮助,而 Microsoft 没有提供帮助,也没有提供 API 来控制当前的 UAC 实现。否则,它会破坏目的。

为了完整起见,有一个进程白名单,可以在不提示的情况下执行一些提升的操作。简而言之,您的可执行文件需要:

由微软签署 执行预定义的操作,例如使用 IFileOperation

我找到的最好的解释是this hack。从那时起它就得到了修复,但对整个事情有了一些了解。

【讨论】:

您不能在创建进程后立即更改分配给进程的安全令牌。

以上是关于在运行时请求管理员权限的主要内容,如果未能解决你的问题,请参考以下文章

程序启动时如何请求管理员权限?

win10激活时(管理员权限运行)报 0x80070005 拒绝访问:所请求的操作需要提升

在 Windows Vista 上请求 Java 应用程序的管理员权限

Win10系统CMD提示请求的操作需要提升权限怎么办

WCF 服务在没有管理员权限的情况下无法运行

Android 权限管理(持续整理)