2014-01-17 3 views
0

я создал две трубы счтения вывода дочернего процесса в то время как он жив

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

Q: Но где я должен поместить код для чтения выход ребенка?


Почему я не могу читать cout и printf с этими трубами?

ответ

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, чтобы вы не закрыли процесс немедленно, и вы можете продолжать общаться с ним. Возможно, даже создайте поток и прочитайте в этом потоке или попросите поток запустить процесс и прочитать .. До вас.

+0

Спасибо вам за право – Yola

Смежные вопросы