2011-06-20 74 views
43

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

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

感谢您的帮助!

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

+3

您可以使用'runas'动词开始另一个过程。 – vcsjones

+2

根据编辑:看起来您需要序列化出程序状态,以便您可以将它读回新的过程。 –

+0

另一种选择 - 使应用程序可以在特殊模式下启动,仅用于执行需要提升privilages的任务,使用IPC来传递数据 - 这将具有不重启应用程序的好处(UI上下文是保存) - 并且UAC窗口将显示相同的应用程序名称(给出了在运行时升级的完整幻象:)) mlvljr

回答

8

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

+0

有没有办法删除特权,以便用户在运行应用程序时不会收到UAC提示?(然后重新获取特权在稍后的时间点用户会得到一个UAC提示) – JonaGik

+5

@JonaGik为了避免UAC提示,不要开始运行提升。根据请求启动另一个应用程序(对应用程序进行分区),或者再次根据请求启动同一应用程序的另一个副本并关闭第一个应用程序。 –

+2

我知道它是_POSSIBLE_,但我不知道如何提升privs ... Windows 7 taskmanager(taskmgr.exe)可以在运行时执行..内部如何?我不知道。以非管理员身份打开taskmgr.exe,然后转到“进程”选项卡并按下“显示所有用户的进程”按钮,然后在运行时请求管理员访问权限。 – hanshenrik

33

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

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

+1。你可以使用runas来生成应用程序的第二个副本作为管理员,然后让它自己终止。 –

+0

它不适用于我:(可能是它的CPP版本问题?你能告诉我你使用了哪个CPP吗? – Jet

+0

自从Vista的时间框架@Jet以来,这一切都与每一个C++一起工作,我建议你问你自己的问题。你的代码,你的C++编译器和版本,以及你的意思是“不起作用”。确保你标记UAC。 –

2

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

要获得同样的结果,您必须拥有TCB权限。换句话说,要在运行时提升进程,您需要在SYSTEM帐户下运行的进程提供帮助,而Microsoft不提供一个,也不需要API来控制当前的UAC实现。否则,它会打败目的。

为了完整起见,有一个进程的白名单,可以执行一些提升的操作,而无需提示。总之,你需要执行:

  • 要通过微软
  • 登录后才能执行预定义的操作,就像IFileOperation

我找到的最好的解释是this hack。从那时起它已经被固定下来,但是对整个事情都有了一些启示。

+0

创建后,您无法更改分配给进程的安全令牌。 –

+0

gr8 ...,谢谢。我会尝试。 – Vipul

8

只有在创建过程中才能提升进程。当一个进程已经运行时,没有办法改变它的安全令牌:它或者运行提升或者不运行。

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


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