【问题标题】:read child process's output while it is alive在子进程处于活动状态时读取子进程的输出
【发布时间】:2014-01-17 14:49:11
【问题描述】:

我用

创建了两个管道
saAttr.bInheritHandle = TRUE; 
...
CreatePipe(&childStdOut_Rd, &childStdOut_Wr, &saAttr, 0);
CreatePipe(&childStdErr_Rd, &childStdErr_Wr, &saAttr, 0);

然后我用下一个 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;

然后关闭父进程中的写句柄: CloseHandle(childStdErr_Wr); CloseHandle(childStdOut_Wr);

我等待子进程完成

WaitForSingleObject(pi.hProcess, INFINITE);

当我在 MSDN 上阅读时,我可以读取 chil 进程的标准输出:

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

问:但是我必须把代码放在哪里才能读取孩子的输出?


为什么我不能用这些管道读取 cout 和 printf?

【问题讨论】:

    标签: c++ stdout stdin io-redirection createprocess


    【解决方案1】:

    我猜是这样的..

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

    它应该打印Hello? Momma?! 10 次。另一个选择是将读数放在WaitForSingleObject 之后,这样您就不会立即关闭进程,并且可以继续与它通信。甚至可能创建一个线程并在该线程中读取,或者让线程产生进程并读取.. 由您决定。

    【讨论】:

      猜你喜欢
      • 2016-03-15
      • 1970-01-01
      • 2021-09-16
      • 2021-12-04
      • 2016-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-06
      相关资源
      最近更新 更多