I wrote this function a while back which you may find useful:
CString SpawnProcessReturnStdOut( char *command_line )
{
CString result = "";
// Setup default pipe security with the bInheritHandle flag set to
// allow pipe handles to be inherited by the child process.
SECURITY_ATTRIBUTES saAttr;
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
// Create the anonymous pipe and store read/write handles
HANDLE hPipeInputRead, hPipeOutputWrite;
CreatePipe( &hPipeInputRead,
&hPipeOutputWrite,
&saAttr,
0 );
// Start up the child process
BOOL bRet = FALSE;
STARTUPINFO si = {0};
PROCESS_INFORMATION pi = {0};
// Make child process use the anonymous pipe for stdin and stdout
si.cb = sizeof(si);
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;
si.hStdInput = hPipeInputRead;
si.hStdOutput = hPipeOutputWrite;
bRet = ::CreateProcess( NULL,
command_line,
NULL,
NULL,
TRUE,
0,
NULL,
NULL,
&si,
&pi );
if (bRet)
{
// Read the contents of the pipe
DWORD dwRead, dwAvail;
CHAR chBuf[256];
BOOL pipe_data = true;
BOOL process_finished;
do
{
process_finished = (WaitForSingleObject (pi.hProcess, 0) == WAIT_OBJECT_0);
// Peek to see if there is any more data in the pipe
PeekNamedPipe( hPipeInputRead,chBuf,255,&dwRead,&dwAvail,NULL);
// Clear buffer to zero
memset(chBuf,0,sizeof(chBuf));
if( dwAvail > 0 )
{
pipe_data = ReadFile( hPipeInputRead, chBuf, 255, &dwRead, NULL);
result += chBuf;
}
}
while( dwAvail > 0 || !process_finished );
// Close the process and pipe handles
CloseHandle (pi.hProcess);
CloseHandle (pi.hThread);
CloseHandle( hPipeInputRead );
CloseHandle( hPipeOutputWrite );
}
return result;
}