如何在启动程序且 UAC 被禁用时强制提示输入凭据?
Posted
技术标签:
【中文标题】如何在启动程序且 UAC 被禁用时强制提示输入凭据?【英文标题】:How to force a prompt for credentials when launching a program and UAC is disabled? 【发布时间】:2015-11-17 15:14:22 【问题描述】:背景
我的应用程序(.NET、C#)执行应用程序内升级。根据安装配置,升级可能需要启动需要管理员权限的单独进程。启动程序的清单指定它需要管理员权限。
这通常工作正常,但如果 UAC 被禁用,并且用户不是管理员,那么它会惨遭失败。见下文。
场景
UAC 已启用,用户是管理员 - Windows 提示提升,程序成功执行。 UAC 已启用,用户不是管理员 - Windows 提示输入凭据,程序成功执行。 UAC 被禁用,并且用户是管理员 - 没有提示,程序执行成功。 UAC 被禁用,并且用户不是管理员 - 没有提示,程序启动但惨遭失败。这第四种情况是我想要解决的。我有一家相当大的客户公司,无论出于何种原因,它都有关闭所有公司 PC 上的 UAC 的政策。
缓解
最简单的解决方案是检测这第四种情况并给予用户指导。当第四种场景生效时,我可以毫无问题地检测到,然后我可以打开一个资源管理器窗口,指向一个包含要执行的程序的目录,以及一个引导用户完成 Shift-Right-Click -> 过程的文本文件“以不同的用户身份运行”。
所需的解决方案
如果我检测到我处于这第四种场景中,那么我会执行一些编码魔术以从我的应用程序自动启动进程AS IF,用户手动选择了“以其他用户身份运行”。
我不知道如何实施此解决方案。正如我所看到的那样,我尝试设置ProcessStartInfo.Verb = "runas"
,但是在没有UAC的情况下这似乎没有任何用处。有什么想法吗?
【问题讨论】:
Imo 正确的动词应该是“runasuser”而不是“runas”。虽然它有一些缺陷,比如进程没有向主程序返回正确的对象,但如果你有一个不关心这些信息的启动器,只是启动单独的 updater.exe,它应该可以正常工作 这是一种大企业场景,您根本无法运行需要提升的程序。您可以要求漂亮请再次启用 UAC 提示,但这仍然无济于事,用户不知道密码。你必须和企业的大佬谈谈,你说“不”,也许你会得到“是”。 @Syberdoor - 非常感谢!这样可行。随时提交答案,我会将其标记为已接受。正如你所说,我没有取回对象,所以我无法检测到该过程何时完成。我可能会利用Process.GetProcessByName()
来检测进程何时退出,然后使用工件来确定成功或失败。听起来合理吗?
我不够专业,也不知道如果您需要在衍生进程和父进程之间进行通信,那么最好的方法是什么,但至少应该是可能的。如果你的名字足够独特并且运行时间很长,检查可能会起作用,或者你甚至可以使用 wcf namedpipes 或其他东西进行进程间通信
只是一个额外的说明,以防将来有人走这条路......无论父进程和子进程之间使用哪种方法进行通信,您可能需要使用类似Elevating user credentials using runasuser verb在您的解决方案中。请记住,用户可以在凭据提示上按 Cancel,在这种情况下,子进程将永远不会启动。
【参考方案1】:
这个例子的正确动词是
ProcessStartInfo.Verb = "runasuser"
触发另一个进程的“以不同用户身份运行”身份验证对话框效果很好。 我发现的一个可能的缺点是您不会返回正确的进程对象,因此您无法获得该新进程的句柄。此外,实际上不可能使用此方法重新启动您自己的应用程序,因为身份验证对话框作为生成应用程序的线程运行,并且只有在身份验证之后才会创建新进程。因此,如果您想“重新启动”您的应用程序,可能需要启动器或其他一些技巧。
【讨论】:
以上是关于如何在启动程序且 UAC 被禁用时强制提示输入凭据?的主要内容,如果未能解决你的问题,请参考以下文章