سؤال

I have created two pipes with

saAttr.bInheritHandle = TRUE; 
...
CreatePipe(&childStdOut_Rd, &childStdOut_Wr, &saAttr, 0);
CreatePipe(&childStdErr_Rd, &childStdErr_Wr, &saAttr, 0);

Then i have created child process with next STARTUPINFO:

                        STARTUPINFO si;
                        ZeroMemory(&si, sizeof(si));
                        si.cb = sizeof(STARTUPINFO);
                        si.dwFlags     = STARTF_USESHOWWINDOW;
                        si.wShowWindow = SW_MINIMIZE;
                        si.hStdError   = childStdErr_Wr;
                        si.hStdOutput  = childStdOut_Wr;
                        si.hStdInput   = INVALID_HANDLE_VALUE;
                        si.dwFlags    |= STARTF_USESTDHANDLES;

Then closed write handles in parent process: CloseHandle(childStdErr_Wr); CloseHandle(childStdOut_Wr);

I wait while child process finishes with

WaitForSingleObject(pi.hProcess, INFINITE);

As i read on MSDN i can read chil process's stdout with:

for (;;) 
{ 
    BOOL bSuccess = ReadFile(childStdOut_Rd, chBuf, bufsize, &dwRead, NULL);
    if(!bSuccess || dwRead == 0) break; 

    bSuccess = WriteFile(hParentStdOut, chBuf, dwRead, &dwWritten, NULL);
    if (!bSuccess) break; 
} 

Q: But where i must put code to read child's output?


Why i can't read cout and printf with these pipes?

هل كانت مفيدة؟

المحلول

Like this I guess..

ChildProcess -- main.cpp:

#include <iostream>
#include <windows.h>


int main()
{
    HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
    if (!hOut)
        return 0;

    DWORD WriteCount = 0;
    char Buffer[1024] = {0};

    strcat(&Buffer[0], "Hello? Momma?!");
    int Length = strlen(Buffer);

    for (int i = 0; i < 10; ++i)
    {
        if (!WriteFile(hOut, Buffer, Length, &WriteCount, 0))
            break;
    }

    return 0;
}

ParentProcess -- main.cpp

#include <iostream>
#include <windows.h>

void RedirectIO(HANDLE &hRead, HANDLE &hWrite)
{
    SECURITY_ATTRIBUTES attr;
    ZeroMemory(&attr, sizeof(attr));
    attr.nLength = sizeof(attr);
    attr.bInheritHandle = true;

    CreatePipe(&hRead, &hWrite, &attr, 0);
    SetHandleInformation(hRead, HANDLE_FLAG_INHERIT, 0);
}

bool CreateChild(std::string CommandLine, DWORD WaitTime, HANDLE hInRead, HANDLE hOutWrite)
{
    STARTUPINFO SI;
    PROCESS_INFORMATION PI;
    ZeroMemory(&SI, sizeof(SI));
    ZeroMemory(&PI, sizeof(PI));

    SI.cb = sizeof(SI);
    SI.hStdError = hOutWrite;
    SI.hStdInput = hInRead;
    SI.hStdOutput = hOutWrite;
    SI.dwFlags |= STARTF_USESTDHANDLES;

    bool success = CreateProcess(0, const_cast<char*>(CommandLine.c_str()), 0, 0, true, NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW, 0, 0, &SI,&PI);

    if (success)
    {
        WaitForSingleObject(PI.hProcess, WaitTime);
        CloseHandle(PI.hProcess);
        CloseHandle(PI.hThread);
    }

    return success;
}

int main()
{
    HANDLE hRead = nullptr;
    HANDLE hWrite = nullptr;

    RedirectIO(hRead, hWrite);
    CreateChild("C:/Users/School/Desktop/ChildProcess/bin/Debug/ChildProcess.exe", INFINITE, nullptr, hWrite);

    DWORD ReadCount = 0;
    char Buffer[1024] = {0};

    std::string data = std::string();

    while(true)
    {
        if (!ReadFile(hRead, Buffer, sizeof(Buffer) / sizeof(char), &ReadCount, 0))
            break;

        if (!ReadCount) break;

        Buffer[ReadCount] = '\0';
        data.append(&Buffer[0], ReadCount);
        std::cout<<"Read From Child:\n\n"<<data<<"\n";
    }

    return 0;
}

It should print Hello? Momma?! 10 times.. Another option is the place the reading right after the WaitForSingleObject so that you don't close the process immediately and you can keep communicating with it. Maybe even create a thread and read in that thread or have the thread spawn the process and read.. Up to you.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top