我正在尝试创建一个模仿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应用程序上的解决方案是什么?
非常感谢,
迈克尔。
答案 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);