【问题标题】:Waiting for ShellExecuteEx (Setting access rights on Windows process)等待 ShellExecuteEx(设置 Windows 进程的访问权限)
【发布时间】:2009-07-17 09:25:55
【问题描述】:

我在 C++ 程序中使用 ShellExecuteEx 函数来启动 Uninstall.lnk 文件。在我的程序中,我想等待卸载程序完成。我的第一次尝试是在SHELLEXECUTEINFO 结构中设置SEE_MASK_NOCLOSEPROCESS 标志,然后在传递给ShellExecuteExSHELLEXECUTEINFO 结构中可用的hProcess 句柄上调用WaitForSingleObject,但似乎仍然会返回早点。

我目前的怀疑是,这是因为 ShellExecuteEx 启动的进程(它是否启动了新的 shell?)创建了新的子进程,但不等待它们。所以我正在尝试创建一个“等待我的子进程及其启动的所有子进程”功能。为此,我正在尝试使用作业对象。

我使用CreateJobObject 创建了一个作业对象,将ShellExecuteEx 返回的进程句柄分配给该作业,然后尝试等待该作业对象。不幸的是,将进程分配给作业失败,我认为这是由于访问权限不足。

有谁知道如何在进程句柄上设置 PROCESS_SET_QUOTA 和 PROCESS_TERMINATE 访问权限(根据 MSDN,这是 AssignProcessToJobObject 成功所必需的),或者以其他方式等待 ShellExecuteEx 启动的进程完成?

更新:我应该指出,我还将启动其他应用程序,而不仅仅是 Uninstall.lnk。其中之一是例如ClickOnce 应用程序,它实际上是一个简单的 XML 文件,文件扩展名为 .application

【问题讨论】:

    标签: c++ windows process shellexecute


    【解决方案1】:

    Vista 使用作业对象来启动链接。因此,您尝试分配给另一个作业对象的进程可能已被分配。

    见:this question

    【讨论】:

    • 好点。实际上,似乎有时(取决于我通过ShellExecuteEx 启动的文件类型),启动的进程已经是作业对象的一部分。不幸的是,不可能打破这种关联。 :-/
    • 好点。使用 ShellExecuteEx 的原因之一是将一大堆责任交给 Shell。如果想要更精准的控制,比如Job控制,就用CreateProcess吧。
    【解决方案2】:

    为什么不执行目标文件而不是打开Uninstall.lnk?您可以使用IShellLink 来获取快捷方式目标。然后你就可以通过 ShellExecuteEx 使用SEE_MASK_NOCLOSEPROCESS 标志来执行目标文件了。

    【讨论】:

    • 如果目标进程生成另一个进程(如 msiexec.exe)并死掉,这将无济于事。
    • 那么你应该执行msiexec.exe或者更好的使用安装程序API。
    • 我很抱歉不准确;我还推出了其他类型的文件,而不仅仅是 .lnk 文件。我还启动普通的 .exe 文件以及 ClickOnce 应用程序(.application 文件)。
    猜你喜欢
    • 2011-08-01
    • 1970-01-01
    • 2015-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-08
    • 2018-12-06
    • 2016-09-28
    相关资源
    最近更新 更多