Reputation: 656
Other than creating pipes for standard in/out/error, is there any easy way in Win32 API to redirect those handles to the parent process? If the child process has a console window, the output/error seems to go to it, rather than the parent's console window, even when the handles are inherited. What I'd really like is for a windowless child process to send its out/error to the parent's console (easily?). Advice appreciated.
Upvotes: 0
Views: 1018
Reputation: 7190
If you only want to display the stdout
and stderr
of your child process to the console of the parent process, you can use AttachConsole(ATTACH_PARENT_PROCESS
) in the child process to attach it to the console of the parent process. Or In parent, specify dwCreationFlags
of CreateProcess
as 0, according to the Creation of a Console:
By default, a console process inherits its parent's console.
(there is no guarantee that input is received by the process for which it was intended. Make sure you don' t need to use the stdin for child process)
However, this method cannot interact with the parent process. If the parent process needs to obtain these output data, it still needs to use Interprocess Communications to send the data to the parent process.
This method allows the child process and the parent process to use the same console, but the parent process cannot directly obtain the output data of the child process. If the parent process needs to get the data, it still needs to use Interprocess Communications to send the data to the parent process.
EDIT:
Here is the sample
child:
#include <windows.h>
#include <iostream>
int main(VOID)
{
AttachConsole(ATTACH_PARENT_PROCESS);
int i = 5;
while (i--)
{
printf("printf\n");
std::cout << "child " << i << std::endl;
fflush(stdout);
Sleep(1000);
}
return 0;
}
parent:
#include <windows.h>
#include <iostream>
int main()
{
STARTUPINFO si = {};
si.cb = sizeof(STARTUPINFO);
PROCESS_INFORMATION pi = {};
WCHAR cmd[] = L"Path\\child.exe";
SECURITY_ATTRIBUTES se = {};
se.nLength = sizeof(SECURITY_ATTRIBUTES);
se.bInheritHandle = true;
se.lpSecurityDescriptor = NULL;
HANDLE hFile = CreateFileW(L"test.txt", GENERIC_WRITE, FILE_SHARE_READ, &se, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
BOOL ret = SetStdHandle(STD_OUTPUT_HANDLE, hFile);
printf("parent1\n");
ret = CreateProcessW(cmd, NULL, 0, 0, 1, 0, 0, 0, &si, &pi);
std::cout << "parent2 " << std::endl;
WaitForSingleObject(pi.hProcess,INFINITE);
system("pause");
}
Another sample:
child
int main(VOID)
{
//AttachConsole(ATTACH_PARENT_PROCESS);
int i = 5;
while (i--)
{
printf("printf\n");
std::cout << "child " << i << std::endl;
fflush(stdout);
Sleep(1000);
}
return 0;
}
parent
int main()
{
SECURITY_ATTRIBUTES se = {};
se.nLength = sizeof(SECURITY_ATTRIBUTES);
se.bInheritHandle = true;
se.lpSecurityDescriptor = NULL;
HANDLE hFile = CreateFileW(L"test.txt", GENERIC_WRITE, FILE_SHARE_READ, &se, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
BOOL ret = SetStdHandle(STD_OUTPUT_HANDLE, hFile);
printf("parent1\n");
STARTUPINFO si = {};
si.cb = sizeof(STARTUPINFO);
si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
si.dwFlags |= STARTF_USESTDHANDLES;
PROCESS_INFORMATION pi = {};
WCHAR cmd[] = L"Path\\child.exe";
CreateProcessW(cmd, NULL, 0, 0, 1, 0, 0, 0, &si, &pi);
std::cout << "parent2 " << std::endl;
WaitForSingleObject(pi.hProcess, INFINITE);
system("pause");
}
Upvotes: 0