Reputation: 2238
According to MSDN this redirects child stdout to parent stdout, but it does not, what is wrong?
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);
using DuplicateHandle does not help:
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);
Upvotes: 5
Views: 8435
Reputation: 758
BOOL ret = CreateProcessA( 0, cmd_line, 0, 0, TRUE, CREATE_NO_WINDOW, 0, 0, & si, & pi);
CREATE_NO_WINDOW causes this behavior, remove it:
BOOL ret = CreateProcessA( 0, cmd_line, 0, 0, TRUE, 0, 0, 0, & si, & pi);
Upvotes: 7
Reputation: 35663
Firstly I second Michael's advice. You shouldn't be using the A versions at all, ever again, unless for some crazy reason you need to support Windows 98. Hint: You don't. You should only ever be using the W versions. Always #define UNICODE
!!!
According to the documentation:
STARTF_USESTDHANDLES
0x00000100
ThehStdInput
,hStdOutput
, andhStdError members
contain additional information.If this flag is specified when calling one of the process creation functions, the handles must be inheritable and the function's
bInheritHandles
parameter must be set to TRUE. For more information, see Handle Inheritance.
The handles returned by GetStdHandle
are not necessarily inheritable handles, they may be non-inheritable or may be pseudo-handles. In fact they may not exist at all, they may be null or INVALID_HANDLE_VALUE -- you need to check for that too.
To get an inheritable handle from a non-inheritable handle or pseudohandle, you need to use DuplicateHandle
Upvotes: 2
Reputation: 598134
Don't pass the parent's stdout/stderr handles directly to the child process. Use CreatePipe()
to create read/write pipe(s), assign their writing endpoints to the child process stdout/stderr handles, then have the parent process use ReadFile()
to read from the pipes and write any received data to its own stdout/stderr as needed. MSDN shows how to use CreatePipe()
for that:
Creating a Child Process with Redirected Input and Output
Upvotes: 1