【问题标题】:How do I know when CreateProcess actually started a process?我怎么知道 CreateProcess 何时真正启动了一个进程?
【发布时间】:2011-02-15 03:09:33
【问题描述】:

我遇到了麻烦,归结为希望 CreateProcessStartProcess。问题是在某些情况下CreateProcess创建 进程时返回true 但系统无法启动 进程。例如,CreateProcess 将成功,即使启动者的其中一个导入无法解析。

根据我希望通过启动此流程实现的具体目标,可能有十几个建议。但是,恐怕这些建议都不会有用,因为我不希望通过启动这个过程来完成任何特别的事情。

一个示例建议可能是针对进程句柄调用WaitForSingleObject,然后调用GetExitCodeProcess。但我不能等待进程退出,因为它可能会永远存在。

另一个示例建议可能是调用WaitForInputIdle,如果我希望通过我可以合理地期望启动者创建的窗口与启动者进行通信,这将很有效。但我不希望这样,我也不能合理地期望那样。据我所知,启动者是一个控制台进程和/或永远不会有消息队列。同样,我不能等待(带着启发式意图)找出答案。

事实上,我不能假设任何关于启动者的事情。

为了更好地了解我在这里的想法,让我们看看问题的另一面。如果该过程没有启动,我需要一个错误代码来告诉我如何建议用户。如果导入全部解决并且主线程意识到它即将跳转到 CRT 启动代码(或等效代码),我得到的错误代码是 ERROR_SUCCESS,太好了!但我实际上对启动器不感兴趣,只是希望在启动器中提供良好的用户体验。

哦,还有一件事:我希望这很简单。我不想写调试器。 :-)

想法?

【问题讨论】:

  • 不管怎样,使用 DEBUG_PROCESS 启动非常简单,但可能会产生您不想要的副作用。
  • 如果您想在您启动的进程无法解析其所有导入时进行捕获,您是否还想在它抛出异常并且没有捕获它时进行捕获?当它决定运行到无效内存和段错误时怎么办?或者如果它因为命令行参数错误而决定终止?从用户体验的角度来看,所有这些“它不起作用”的情况都与非技术人员非常相似。
  • 是的,所以我想我应该澄清一下我确实想假设一件事:该过程负责报告自己的失败。
  • 当找不到它要使用的DLL时,它不应该负责报告吗?
  • 当然可以这样说,但是由于导入解析发生在主线程进入 CRT 之前,并且由于大多数代码,尤其是移植代码是在不知道需要导入哪些符号以及需要导入哪些符号的情况下编写的链接器将负责,我希望能够在启动器中报告这些故障。基本上,大多数程序都认为宇宙是从 main 开始的,我想宠爱它们。

标签: winapi createprocess waitforsingleobject


【解决方案1】:

一个示例建议可能是针对进程句柄调用 WaitForSingleObject,然后调用 GetExitCodeProcess。但我不能等待进程退出,因为它可能会永远存在。

您为什么不等待进程句柄一段合理的时间。如果计时器在句柄发出信号之前到期,则可以假定该进程已启动并正在运行。如果句柄先发出信号,并且退出代码是正确的,那么您可以假定它运行并成功完成。

如果您还没有看到,Raymond Chen's blog 中提到了 CreateProcess vs started 问题。

老实说,如果您不愿意接受启发式算法(例如,“三秒后它没有以失败代码结束,因此我们假设一切正常”),那么您将不得不写一个 '调试器”,我的意思是检查已启动进程的内部。

【讨论】:

  • 是的,启发式是我希望避免的。如果必须,我会这样做——这比编写调试器要好——但真正的解决方案会更好。
  • 您可以执行类似 AppInit DLL 的操作,以报告每个启动的进程。但是你的目标是什么?你认为一个进程成功的条件是什么?每个DLL都加载了吗? DLL 可以随时显式加载,并且应用程序可能会因错误而退出,因此报告隐式 DLL 加载完成实际上只是另一种启发式方法。
  • 我很高兴让动态加载的 DLL 失败。我所追求的只是确定应用程序的感知宇宙是否开始于 main 的第一行(或者,如果它很疯狂,则为全局对象的第一个构造函数)是否已经存在。如果该应用程序已经开始工作,那就足够了。如果它后来因任何原因失败,那很好。这是它自己的问题。
  • 直到现在我才知道 AppInit DLL 的存在。我仍然在他们周围环绕我的头。我的第一反应是避免在全球范围内做一些事情,但我会在我的舌头上晃悠一会儿。
【解决方案2】:

这个问题已经很久没有答案了,我怀疑可以肯定地说答案是:“你不能。”

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-20
    • 1970-01-01
    • 1970-01-01
    • 2011-04-10
    • 2015-12-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多