【发布时间】:2014-12-21 03:28:10
【问题描述】:
我正在尝试创建一个模仿 cmd.exe 的应用程序。
我的应用程序应该能够启动新进程,打印它们的输出,并在子进程完成后完成。
这适用于控制台应用程序,但我在使用 GUI 应用程序时遇到问题。
我的逻辑如下:
在父进程中,创建一个 STDOUT 重定向管道(将由子进程使用)。 该管道将被继承给子级,并将用作 STDOUT。 这是通过使用 CreateProcess + StartupInformation 结构来实现的(更多信息here)。
创建子进程后,我使用 ReadFile 从管道中读取。 一旦 ReadFile 失败(或读取 0 个字节),我知道会话已经结束。
我对 GUI 应用程序的问题是它们挂在 ReadFile 上并且永远不会结束,只有在进程已终止时。
可以说这是一种正常的行为(我同意),但这不是 cmd.exe 的工作方式。
可以打开 cmd.exe 并启动 calc.exe,你会发现 cmd 并没有挂起,而是直接准备好进行新的输入。
就像 cmd.exe “知道”这是一个 GUI 应用程序,他们不需要等待。
我的问题是如何模仿 cmd.exe,防止在 GUI 应用程序上挂起的解决方案是什么?
非常感谢,
迈克尔。
【问题讨论】:
-
非常感谢您的评论.. :(
-
判断进程是否退出,检查进程句柄是否有信号。如果要轮询,可以使用超时为零的 WaitForSingleObject。将输出重定向到管道将改变许多命令行应用程序的行为,即它们将开始缓冲输出,这通常是不可取的,而且往往是致命的。默认情况下,输出将转到控制台,这就是 cmd.exe 所做的。
-
我不确定 cmd.exe 如何确定子进程是控制台还是 GUI 进程。一种解决方案是自己读取可执行文件头,格式已记录在案。您也许可以尝试启动该进程,然后使用 GetConsoleProcessList 来查看该进程是否已附加到控制台。 (为了避免竞争情况,我想你应该启动暂停的进程,只有在检查控制台进程列表后才能恢复它。)
标签: windows user-interface process io-redirection