http://www.codeguru.com/cpp/misc/misc/Article.php/c277
Xinhai Kang (View Profile) April 4, 1999
ENVIRONMENT: Visual C 6.0 SP2, Windows NT 4.0 SP4 (Continued)
I have the thought of redirecting output of WIN32 console programs to a pipe or a file long ago, but I do not know to do at all at first, finally I searched through Microsoft MSDN and found a way, the code pasted below was copied From MSDN Sample Core Except Some Changes in function CreateChildProcess (), WHERE I stressed in the code.
In The Demo Source, I Redirect The stdout of cmd.exe to a pipe and start a thread to read from this Pipe, the all That cmd.exe output Was redirected to the pipe where i amread.
Bool cshellview :: createshellredirect () {security_attributes saattr; Bool Fsuccess
// set the binherithandle flag so pipe handles are inherited.saattr.nlength = sizeof (security_attributes); sattr.binherithandle = true; sattr.lpsecurityDescriptor = null;
// The steps for redirecting child process's STDOUT: // 1. Save current STDOUT, to be restored later.// 2. Create anonymous pipe to be STDOUT for child process.// 3. Set STDOUT of the parent process to be write .
// Save the Handle to the current stdout.hsavestdout = getstdhandle (std_output_handle);
// Create a Pipe for the child process's stdout.if (! CreatePipe (& Hchildstdoutr, & Hchildstdoutwr, & sattr, 0)) {trace0 (_T ("stdout pipe code failed / n"); return false;}
// Set a write handle to the pipe to be STDOUT.if (SetStdHandle (STD_OUTPUT_HANDLE, hChildStdoutWr)!) {TRACE0 (_T ( "Redirecting STDOUT failed / n")); return FALSE;} // Create noninheritable read handle and close the inheritable read handle.fSuccess = DuplicateHandle (GetCurrentProcess (), hChildStdoutRd, GetCurrentProcess (), & hChildStdoutRdDup, 0, FALSE, DUPLICATE_SAME_ACCESS); if (fSuccess!) {TRACE0 (_T ( "DuplicateHandle failed / n")); return FALSE; } CloseHandle (HChildstdout);
// the steps for redirecting child process's stdin: // 1. Save current stdin, to be rest, limited, to be stdin for child processing.//3. set stdin of the parent to be the read Handle to the // pipe, so it is inherited by the child process.// 4. Create a noninheritable duplicate of the write handle, // and close the inheritable write.
// Save the handle to the current stdin.hsavestdin = getstdhandle (std_input_handle);
// Create a Pipe for the child process's stdin.if (! CreatePipe (& HchildstdinRD, & Hchildstdinwr, & sattr, 0)) {trace0 (_T ("stdin pipe code failed / n"); return false;} // set a read handle to the pipe to be STDIN.if {TRACE0 (_T ( "Redirecting Stdin failed / n")); return FALSE;} (SetStdHandle (STD_INPUT_HANDLE, hChildStdinRd)!) // Duplicate the write handle to the pipe so it is not inherited.fSuccess = DuplicateHandle (GetCurrentProcess (), hChildStdinWr, GetCurrentProcess (), & hChildStdinWrDup, 0, FALSE, // not inheritedDUPLICATE_SAME_ACCESS); if (fSuccess!) {TRACE0 (_T ( "DuplicateHandle failed / n")); return FALSE; } CloseHandle (HchildstDinWr);
// Now create the child process.if (CreateChildProcess (dwProcessId)!) {TRACE0 (_T ( "CreateChildProcess failed / n")); return FALSE;} // After process creation, restore the saved STDIN and STDOUT.if (! SetStdHandle (STD_INPUT_HANDLE, hSaveStdin)) {TRACE0 (_T ( "Re-redirecting Stdin failed / n")); return FALSE;} if (SetStdHandle (STD_OUTPUT_HANDLE, hSaveStdout!)) {TRACE0 (_T ( "Re-redirecting Stdout failed / n ")); return FALSE;} m_pReadThread = fxBeginThread ((AFX_THREADPROC) ReadPipeThreadProc, (LPVOID) this); if (m_pReadThread) {TRACE0 (_T (!" Can not start read-redirect thread / n "));! return FALSE Return True;} Bool Cshellview :: CreateChildProcess (DWORD & DWPROCESSID) {Process_information Piprocinfo; Startupinfo SistartInfo;
// Set up members of STARTUPINFO structure.ZeroMemory (& siStartInfo, sizeof (STARTUPINFO)); siStartInfo.cb = sizeof (STARTUPINFO); // * Note here thedwFlags should be STARTF_USESTDHANDLES, which is descripted in WIN32 APIdocument, but this wasomitted in MSDN Sample * / sistartinfo.dwflags = startf_usestdhandles; sistartinfo.hstdinput = hchildstdinrd; sistartinfo.hstdoutput = hchildstdoutwr; sistartinfo.hstder = hChildstdOutwr;
/// tchar shellcmd [_max_path]; if (! GetEnvironment ", shellcmd, _max_path)) Return false; #ifdef _unicode_tcscat (shellcmd, _t (" / u ")))); # else_tcscat (shellcmd, _t ( "/ A")); # endif // Create the child process.BOOL ret = CreateProcess (NULL, shellCmd, // applicatin nameNULL, // process security attributesNULL, // primary thread security attributesTRUE, // handles are inheritedDETACHED_PROCESS, // creation flagsNULL, // use parent's environmentNULL, // use parent's current directory & siStartInfo, // STARTUPINFO pointer & piProcInfo); // receives PROCESS_INFORMATIONif (ret) dwProcessId = piProcInfo.dwProcessId; return ret;} Download source - 5 KB
Date last Updated: April 4, 1999