根据MSDN,这将子stdout重定向到父stdout,但它没有,有什么问题?
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);
答案 0 :(得分:5)
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);
答案 1 :(得分:2)
首先,我是第二个迈克尔的建议。你不应该再使用A版本,除非出于某些疯狂的原因你需要支持Windows 98.提示:你没有。您应该只使用W版本。总是#define UNICODE
!!!
根据文件:
STARTF_USESTDHANDLES
0x00000100
hStdInput
,hStdOutput
和hStdError members
包含其他信息。如果在调用其中一个进程创建时指定了此标志 函数,句柄必须是可继承的和函数的
bInheritHandles
参数必须设置为TRUE。欲获得更多信息, 请参阅处理继承。
GetStdHandle
返回的句柄不一定是可继承的句柄,它们可能是不可继承的,也可能是伪句柄。实际上它们可能根本不存在,它们可能为null或INVALID_HANDLE_VALUE - 您也需要检查它。
要从不可继承的句柄或伪句柄获取可继承的句柄,您需要使用DuplicateHandle
答案 2 :(得分:1)
不要将父级的stdout / stderr句柄直接传递给子进程。使用CreatePipe()
创建读/写管道,将其写入端点分配给子进程stdout / stderr句柄,然后让父进程使用ReadFile()
从管道读取并写入任何接收到的数据根据需要自己的stdout / stderr。 MSDN显示了如何使用CreatePipe()
: