【问题标题】:CreateProcess succeeds, but GetExitCodeProcess returns C0000142CreateProcess 成功,但 GetExitCodeProcess 返回 C0000142
【发布时间】:2012-11-05 16:20:48
【问题描述】:

我正在尝试使用类似于this code 的 CreateProcessAsUser() API 从服务启动用户模式进程。我的代码在 99% 的情况下都能正常工作,除了 API 有时会成功,我从 PROCESS_INFORMATION 结构中获取进程句柄,但进程本身并没有出现在我打算在其中运行的交互式用户会话中.

有趣的是,如果我在进程句柄上调用 GetExitCodeProcess(),它会成功并返回代码 0xC0000142。知道为什么吗?

【问题讨论】:

  • 失败时,能不能完全启动子进程?您尝试启动的 .exe 是否可能依赖于缺少的 DLL?
  • 返回码肯定符合行为,它是 STATUS_DLL_INIT_FAILED。这肯定会阻止该过程开始。它使用的 DLL 之一从其 DllMain() 入口点返回 FALSE。你需要在你的开发机器上重现这个,这样你才能调试它。
  • @HansPassant 和 MichaelSh 感谢您的建议。我需要尝试登录该用户会话并查看是否可以手动启动进程。问题是它不会一直发生......但是,我的问题是为什么 CreateProcessAsUser() 在它显然没有启动任何东西时返回 TRUE?
  • 我发现这篇文章可以解释我所看到的“桌面堆耗尽”。对我来说这听起来很可能:blogs.technet.com/b/askperf/archive/2007/07/24/…

标签: c++ winapi process


【解决方案1】:

错误 0xC0000142 是 STATUS_DLL_INIT_FAILED(我使用 Error Code Lookup Tool 确定了这一点)。一个快速的谷歌找到了this question,上面写着:

此问题的最常见原因是链接到user32.dll 的程序在无法与系统的窗口站和桌面对话的上下文中运行。通常,诸如代理之类的服务在其自己的窗口站和桌面中运行,并且 user32 程序运行良好,但是任何显示对话框的程序都会挂起,而人类没有机会看到错误消息或关闭对话框.

所以,如果您没有使用来自user32.dll 的任何函数,您应该删除该依赖项。如果您正在使用该 DLL,那么我不确定您应该做什么。一种选择是使用 LoadLibrary 动态加载 DLL 并在成功时使用它(即您有一个有效的窗口会话),或者在失败时回退到失败模式。

【讨论】:

  • 谢谢。我会尽力。虽然不使用 user32.dll 有点困难,但你知道……我的代码肯定不会显示任何用户内容。它所做的只是打开一个全局命名事件并设置它,然后在错误代码中返回结果。
  • 如果您运行低完整性进程但如果您运行作为服务启动的中等完整性(或更高)完整性则不会发生这种情况?
  • 支持错误代码查找工具的链接,因为这些天在谷歌上搜索错误代码是一件很痛苦的事情。
  • @ahmd0 我遇到了完全相同的问题。它有时有效,有时无效。你找到解决办法了吗?感谢您的回复!
  • @tmighty:是的。确保子进程启动正常的唯一方法是在您的主机进程中创建一个(全局)命名事件,使用事件的security descriptor 使其在子进程中可访问,然后在子进程启动并初始化时打开该命名事件并发出信号。最后从宿主进程首先等待进程句柄,然后检查命名事件是否已发出信号。
【解决方案2】:

如果 CreateProcess...() API 可以成功创建内部进程对象并开始初始化,则返回 TRUE;他们不会等待进程加载并开始运行其可执行映像。在某些情况下,稍后的初始化会失败,但从内核的角度来看,它仍然是一个成功的进程创建。

【讨论】:

  • 好点。谢谢。那么知道我的流程已经“确定”启动的正确方法是什么?
  • 除非您可以通过管道或其他方式直接与进程通信,否则我认为最好的方法是在 CreateProcess() 之后稍等片刻,然后调用 GetExitCodeProcess() 来检查 STILL_ACTIVE 返回码。
  • 或使用WaitForInputIdle()
  • WaitForInputIdle() 在控制台模式程序的情况下并不能完全满足他的要求。如果它只是带有消息泵的应用程序,那么它会起作用。
  • @RemyLebeau:除了 HerrJoebob 所说的,WaitForInputIdle 不能从服务中调用。在这种情况下它总是会失败。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-28
  • 1970-01-01
  • 2019-07-10
相关资源
最近更新 更多