문제

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