处理STDOUT重定向与GUI应用程序挂起

时间:2014-10-25 12:28:04

标签: windows user-interface process io-redirection

我正在尝试创建一个模仿cmd.exe的应用程序。

我的应用程序应该能够启动新进程,打印输出,并在子进程完成后完成。

这可以找到控制台应用程序,但我的GUI应用程序有问题。

我的逻辑如下:

  1. 在父进程中,创建一个STDOUT重定向管道(将由子进程使用)。 此管道将继承到子管道,并将用作STDOUT。 这是通过使用CreateProcess + StartupInformation结构(更多信息here)来实现的。

  2. 创建子进程后,我使用ReadFile从管道中读取。 一旦ReadFile失败(或读取0字节),我就知道会话已经结束。

  3. 我对GUI应用程序的问题是它们挂在ReadFile上并且永远不会结束,只有在进程被终止时才会结束。

    可以说这是一种正常的行为(我同意),但这不是cmd.exe的工作方式。

    可以打开cmd.exe并启动calc.exe,您会注意到cmd没有挂起并且已经准备好接受新输入了。

    就像cmd.exe“知道”这是一个GUI应用程序,他们无需等待。

    我的问题是我如何模仿cmd.exe,防止挂在GUI应用程序上的解决方案是什么?

    非常感谢,

    迈克尔。

1 个答案:

答案 0 :(得分:0)

感谢您的回复,但他们没有解决问题。

我自己找到了我的逆转cmd.exe及其令人尴尬的简单。

cmd.exe不会通过更改子进程STD句柄来重定向IO,它可以在程序集中清楚地看到。

那么如何将子进程输出打印到屏幕上?

似乎如果一个控制台应用程序试图在另一个控制台应用程序上调用CreateProcess,则不会打开新的控制台。面对新的流程将会#34;生活"在父进程的控制台内。如果需要打开2个控制台,则应指定CREATE_NEW_CONSOLE标志。

那么cmd.exe是如何工作的?

它只是调用CreateProcess,没有花哨的管道或类似的东西。

如果子进程是控制台应用程序,其输出将打印到cmd.exe控制台(因为只存在一个控制台)。

如果子进程不是控制台应用程序,它将被创建,cmd.exe将准备就绪。

以下代码就是您所需要的:

STARTUPINFO si;
PROCESS_INFORMATION pi;

memset(&pi, 0, sizeof(pi));
memset(&si, 0, sizeof(si));
si.cb = sizeof(si);
CreateProcessA(NULL, "ipconfig", NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);