CreateProcess:将子标准输出重定向到C++/Windows中的父标准输出



根据 MSDN,这会将子标准输出重定向到父标准输出,但它没有,有什么问题?

   PROCESS_INFORMATION pi;
   STARTUPINFOA si;
   ZeroMemory( &si, sizeof(si) );
   si.cb = sizeof(si);
   ZeroMemory( &pi, sizeof(pi) );
   si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
   si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
   si.dwFlags |= STARTF_USESTDHANDLES;
   BOOL ret = CreateProcessA( 0, cmd_line, 0, 0, TRUE, CREATE_NO_WINDOW, 0, 0, & si, & pi);

使用 DuplicateHandle 无济于事:

HANDLE out, err;//global variables
...
PROCESS_INFORMATION pi;
STARTUPINFOA si;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );  
BOOL ret = DuplicateHandle( GetCurrentProcess(), GetStdHandle(STD_OUTPUT_HANDLE),  GetCurrentProcess(), &out, 0, TRUE, DUPLICATE_SAME_ACCESS);//todo check ret
ret = DuplicateHandle( GetCurrentProcess(), GetStdHandle(STD_ERROR_HANDLE),  GetCurrentProcess(), &err, 0, TRUE, DUPLICATE_SAME_ACCESS);//todo check ret
si.hStdOutput = out;
si.hStdError = err;
si.dwFlags |= STARTF_USESTDHANDLES;
ret = CreateProcessA( 0, cmd_line, 0, 0, TRUE, CREATE_NO_WINDOW, 0, 0, & si, & pi);

BOOL ret = CreateProcessA( 0, cmd_line, 0, 0, TRUE, CREATE_NO_WINDOW, 0, 0, & si, & pi);

CREATE_NO_WINDOW导致此行为,请将其删除:

BOOL ret = CreateProcessA( 0, cmd_line, 0, 0, TRUE, 0, 0, 0, & si, & pi);

首先,

我支持迈克尔的建议。你根本不应该再使用A版本,除非出于某种疯狂的原因你需要支持Windows 98。提示:你没有。您应该只使用 W 版本。始终#define UNICODE !!!

根据文档:

STARTF_USESTDHANDLES 0x00000100 hStdInputhStdOutputhStdError members包含其他信息。

如果在调用其中一个进程创建时指定了此标志 函数,句柄必须是可继承的,并且函数的 bInheritHandles参数必须设置为 TRUE。欲了解更多信息, 请参阅处理继承。

GetStdHandle返回的句柄不一定是可继承的句柄,它们可能是不可继承的,也可能是伪句柄。事实上,它们可能根本不存在,它们可能是空的或INVALID_HANDLE_VALUE的——你也需要检查一下。

若要从不可继承句柄或伪句柄获取可继承句柄,需要使用DuplicateHandle

不要将父进程的 stdout/stderr 句柄直接传递给子进程。使用 CreatePipe() 创建读/写管道,将其写入终结点分配给子进程 stdout/stderr 句柄,然后让父进程使用 ReadFile() 从管道读取,并根据需要将任何接收到的数据写入其自己的 stdout/stderr。 MSDN 显示了如何使用CreatePipe()来实现这一点:

创建具有重定向输入和输出的子进程

最新更新