Andrew
Andrew

Reputation: 656

Can I send output from a Windows child process to the parent?

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

Answers (1)

Drake Wu
Drake Wu

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");
}

result: enter image description here

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

Related Questions