Reputation: 19033
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?
Upvotes: 0
Views: 294
Reputation: 23500
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.
Upvotes: 1