启动新进程时绕过提升
好的,这是我的问题:我正在尝试启动第三方应用程序。该应用程序显然被配置为需要提升,大概是通过嵌入的清单。我的程序在非管理用户的上下文中运行,并且我希望第三方应用程序在相同的上下文中运行。
当我调用 CreateProcess 时,它返回错误代码 740,“请求的操作需要提升”。
我尝试过 CREATE_PRESERVE_CODE_AUTHZ_LEVEL 标志,这听起来很相关,但没有什么区别。
第三方应用程序无需管理员权限即可运行,例如,如果我禁用 UAC,然后以非管理员身份运行它。
预先感谢您提供的任何提示/想法。
OK, here's my problem: I'm trying to launch a third-party application. This application is apparently configured to require elevation, presumably via an embedded manifest. My program is running in the context of a non-administrative user, and I want the third-party application to run in the same context.
When I call CreateProcess it returns error code 740, "The requested operation requires elevation."
I've tried the CREATE_PRESERVE_CODE_AUTHZ_LEVEL flag which sounded relevant but it made no difference.
The third party application does work without administrator privilege, e.g., if I disable UAC and then run it as a non-administrator.
Thanks in advance for any tips/ideas you may have.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
恐怕没有办法解决这个问题。
如果启用了 UAC 并且程序表明它需要提升,则系统会尝试以提升的方式运行此进程。如果您没有提升权限,
CreateProcess
将不会启动这样的进程。使用
ShellExecute
或ShellExecuteEx
函数启动此第三方应用程序。如果用户单击“是”,这些功能将显示 UAC 确认并启动该过程。启动此第三方应用程序的 UI 元素应具有 UAC-shield,以通知用户将显示 UAC 确认。I'm afraid there's no way to workaround it.
If UAC is enabled and program manifests that it requires elevation, then the system tries to run this process as elevated.
CreateProcess
would not start such a process if you're not elevated.Use
ShellExecute
orShellExecuteEx
functions to start this third-party application. These functions will display UAC confirmation and start the process if user clicks Yes. Your UI element which starts this third-party application should have UAC-shield to notify users that UAC confirmation will be displayed.将进程的环境变量 __compat_layer 设置为 RunAsInvoker。如果设置了这个环境变量,CreateProcess就会成功。
您可以使用SetEnvironmentVariable 用于此目的的函数。
Set the environment variable __compat_layer for your process to RunAsInvoker. If this environment variable is set, CreateProcess will succeed.
You can use the SetEnvironmentVariable function for this purpose.
对于一些名称中包含 UPDATE 或 SETUP 或 INSTALL 的非常简单的程序,也需要此提升;与清单无关。我们在 Win2008 上运行的 PICK BASIC 中编写代码,如果我们编写一个名为 UPDATE.TEST 的 HELLO WORLD 程序,我们无法在没有提升的情况下运行它。我们需要做的就是重命名程序来修复...但是很烦人,顺便说一句。
This elevation is also required on some very simple programs that have UPDATE or SETUP or INSTALL in their names; nothing to do with a manifest. We write code in PICK BASIC that runs on Win2008 and if we write a HELLO WORLD program called UPDATE.TEST we can't run it without elevation. All we need to do is rename the program to fix... But annoying, and btws.
另一种可能的解决方案是使用 Microsoft 应用程序兼容性工具包,用于创建和安装应用RunAsInvoker 修复 或 RunAsHighest 修复有问题的应用程序。尽管文档没有说明这是否适用于在清单中设置了 requireAdministrator 的应用程序,但我已经测试过它并且它对我有用。
您可以使用 sdbinst 命令以编程方式安装兼容性数据库线工具。
(在大多数情况下,Norbert 的答案使用起来要简单得多,但可能存在边缘情况。特别是,使用如果您的程序不直接负责启动有问题的可执行文件,则兼容性修复可能更可取。)
Another possible solution is to use use the Microsoft Application Compatibility Toolkit to create and install a custom compatibility database that applies the RunAsInvoker fix or the RunAsHighest fix to the application in question. Although the documentation does not say whether or not this works for applications that have requireAdministrator set in the manifest, I have tested this and it works for me.
You can install a compatibility database programmatically using the sdbinst command-line tool.
(In most scenarios, Norbert's answer will be considerably simpler to use, but there may be edge cases. In particular, using a compatibility fix may be preferable if your program is not directly responsible for launching the problematic executable.)