Creating a child process with redirected Input and Output

Source: Internet
Author: User

The example in this topic demonstrates how to create a child process usingCreateProcess

Function from a console process. It also demonstrates a technique
Using anonymous pipes to redirect the child process's standard input and
Output handles. Note that named pipes can also be used to redirect
Process I/O.

The
Createpipe

Function uses
Security_attributes

Structure to create inheritable handles to the read and write ends
Two pipes. The read end of one pipe serves as standard input for
Child process, and the write end of the other pipe is the standard
Output for the child process. These pipe handles are specified in
Startupinfo

Structure, which makes them the standard handles inherited by the child process.

The parent process uses the opposite ends of these two pipes to write
To the child process's input and read from the child process's output.
As specified inStartupinfo

Structure, these handles are also inheritable. However, these handles
Must not be inherited. Therefore, before creating the child process,
Parent process uses
TheSethandleinformation

Function to ensure that the write handle for the child process's
Standard input and the read handle for the child process's Standard
Input cannot be inherited. For more information, see
Pipes
.

The following is the code for the parent process. It takes a single command-line argument: The name of a text file.

 

# Include <windows. h> <br/> # include <tchar. h> <br/> # include <stdio. h> <br/> # include <strsafe. h> <br/> # define bufsize 4096 </P> <p> handle g_hchildstd_in_rd = NULL; <br/> handle g_hchildstd_in_wr = NULL; <br/> handle g_hchildstd_out_rd = NULL; <br/> handle g_hchildstd_out_wr = NULL; <br/> handle g_hinputfile = NULL; </P> <p> void createchildprocess (void ); <br/> void writetopipe (void); <br/> void readfrompipe (VO ID); <br/> void errorexit (ptstr); </P> <p> int _ tmain (INT argc, tchar * argv []) <br/>{< br/> security_attributes saattr; </P> <p> printf ("/n-> Start of parent execution. /n "); <br/> // set the binherithandle flag so pipe handles are inherited. </P> <p> saattr. nlength = sizeof (security_attributes); <br/> saattr. binherithandle = true; <br/> saattr. lpsecuritydescriptor = NULL; <br/> // create a pipe for the CH ILD process's stdout. </P> <p> If (! Createpipe (& g_hchildstd_out_rd, & g_hchildstd_out_wr, & saattr, 0) <br/> errorexit (text ("stdoutrd createpipe ")); <br/> // ensure the read handle to the pipe for stdout is not inherited. <br/> If (! Sethandleinformation (g_hchildstd_out_rd, handle_flag_inherit, 0) <br/> errorexit (text ("stdout sethandleinformation ")); <br/> // create a pipe for the child process's stdin. </P> <p> If (! Createpipe (& g_hchildstd_in_rd, & g_hchildstd_in_wr, & saattr, 0) <br/> errorexit (text ("stdin createpipe ")); <br/> // ensure the write handle to the pipe for stdin is not inherited. </P> <p> If (! Sethandleinformation (g_hchildstd_in_wr, handle_flag_inherit, 0) <br/> errorexit (text ("stdin sethandleinformation"); </P> <p> // create the child process. </P> <p> createchildprocess (); <br/> // get a handle to an input file for the parent. <br/> // This example assumes a plain text file and uses string output to verify data flow. </P> <p> If (argc = 1) <br/> errorexit (text ("Please specify an input F Ile. /n "); <br/> g_hinputfile = createfile (<br/> argv [1], <br/> generic_read, <br/> 0, <br/> null, <br/> open_existing, <br/> file_attribute_readonly, <br/> null); <br/> If (g_hinputfile = invalid_handle_value) <br/> errorexit (text ("createfile"); </P> <p> // write to the pipe that is the standard input for a child process. <br/> // data is written to the pipe's buffers, so it is not necessary Wait <br/> // until the child process is running before writing data. </P> <p> writetopipe (); <br/> printf ("/n-> contents of % s written to child stdin pipe. /n ", argv [1]); </P> <p> // read from pipe that is the standard output for child process. </P> <p> printf ("/n-> contents of child process stdout:/n", argv [1]); <br/> readfrompipe (); <br/> printf ("/n-> end of parent execution. /n "); <br/> // The remaini Ng open handles are cleaned up when this process terminates. <br/> // to avoid resource leaks in a larger application, close handles explicitly. <br/> return 0; <br/>}</P> <p> void createchildprocess () <br/> // create a child process that uses the previusly created pipes for stdin and stdout. <br/>{< br/> tchar szjavasline [] = text ("child"); <br/> process_information piprocinfo; <br/> startupinfo sistar Tinfo; <br/> bool bsuccess = false; </P> <p> // set up members of the process_information structure. </P> <p> zeromemory (& piprocinfo, sizeof (process_information); </P> <p> // set up members of the startupinfo structure. <br/> // This structure specifies the stdin and stdout handles for redirection. </P> <p> zeromemory (& sistartinfo, sizeof (startupinfo); <br/> sistartinfo. CB = sizeof (startupinfo); <br/> Sistartinfo. hstderror = g_hchildstd_out_wr; <br/> sistartinfo. hstdoutput = g_hchildstd_out_wr; <br/> sistartinfo. hstdinput = g_hchildstd_in_rd; <br/> sistartinfo. dwflags | = startf_usestdhandles; </P> <p> // create the child process. </P> <p> bsuccess = CreateProcess (null, <br/> szcmdline, // command line <br/> null, // process security attributes <br/> null, // primary thread security attributes <br /> True, // handles are inherited <br/> 0, // creation flags <br/> null, // use parent's Environment <br/> null, // use parent's current directory <br/> & sistartinfo, // startupinfo pointer <br/> & piprocinfo ); // es process_information </P> <p> // if an error occurs, exit the application. <br/> If (! Bsuccess) <br/> errorexit (text ("CreateProcess ")); <br/> else <br/> {<br/> // close handles to the child process and its primary thread. <br/> // some applications might keep these handles to monitor the status <br/> // of the child process, for example. <br/> closehandle (piprocinfo. hprocess); <br/> closehandle (piprocinfo. hthread); <br/>}</P> <p> void writetopipe (void) <br/> // read from a f Ile and write its contents to the pipe for the child's stdin. <br/> // stop when there is no more data. <br/>{< br/> DWORD dwread, dwwritten; <br/> char chbuf [bufsize]; <br/> bool bsuccess = false; </P> <p> for (;) <br/>{< br/> bsuccess = readfile (g_hinputfile, chbuf, bufsize, & dwread, null ); <br/> If (! Bsuccess | dwread = 0) break; </P> <p> bsuccess = writefile (g_hchildstd_in_wr, chbuf, dwread, & dwwritten, null); <br/> If (! Bsuccess) break; <br/>}</P> <p> // close the pipe handle so the child process stops reading. </P> <p> If (! Closehandle (g_hchildstd_in_wr) <br/> errorexit (text ("stdinwr closehandle"); <br/>}</P> <p> void readfrompipe (void) <br/> // read output from the child process's pipe for stdout <br/> // and write to the parent process's pipe for stdout. <br/> // stop when there is no more data. <br/>{< br/> DWORD dwread, dwwritten; <br/> char chbuf [bufsize]; <br/> bool bsuccess = false; <br/> handle hparentstdout = Getstdhandle (std_output_handle); <br/> // close the write end of the pipe before reading from the <br/> // read end of the pipe, to control child process execution. <br/> // The pipe is assumed to have enough buffer space to hold the <br/>/data the child process has already written to it. </P> <p> If (! Closehandle (g_hchildstd_out_wr) <br/> errorexit (text ("stdoutwr closehandle"); </P> <p> (;;) <br/>{< br/> bsuccess = readfile (g_hchildstd_out_rd, chbuf, bufsize, & dwread, null); <br/> If (! Bsuccess | dwread = 0) break; <br/> bsuccess = writefile (hparentstdout, chbuf, <br/> dwread, & dwwritten, null ); <br/> If (! Bsuccess) break; <br/>}</P> <p> void errorexit (ptstr lpszfunction) <br/> // format a readable error message, display a message box, <br/> // and exit from the application. <br/>{< br/> lpvoid lpmsgbuf; <br/> lpvoid lpdisplaybuf; <br/> dword dw = getlasterror (); <br/> formatmessage (<br/> format_message_allocate_buffer | <br/> format_message_from_system | <br/> format_message_ignore_inserts, <br/> null, <br/> DW, <br/> makelangid (lang_neutral, sublang_default), <br/> (lptstr) & lpmsgbuf, <br/> 0, null); <br/> lpdisplaybuf = (lpvoid) localalloc (lmem_zeroinit, <br/> (lstrlen (lpctstr) lpmsgbuf) + lstrlen (lpctstr) lpszfunction) + 40) * sizeof (tchar )); <br/> stringcchprintf (lptstr) lpdisplaybuf, <br/> localsize (lpdisplaybuf)/sizeof (tchar), <br/> text ("% s failed with error % d: % s "), <br/> lpszfunction, DW, lpmsgbuf); <br/> MessageBox (null, (lpctstr) lpdisplaybuf, text (" error "), mb_ OK ); <br/> localfree (lpmsgbuf); <br/> localfree (lpdisplaybuf); <br/> exitprocess (1); <br/>}</P> <p>

 

 

 

The following is the code for the child process. It uses the inherited
Handles for stdin and stdout to access the pipe created by the parent.
The parent process reads from its input file and writes the information
To a pipe. The child vertex es text through the pipe using stdin and
Writes to the pipe using stdout. The parent reads from the read end
The pipe and displays the information to its stdout.

 

# Include <windows. h> <br/> # include <stdio. h> <br/> # define bufsize 4096 </P> <p> int main (void) <br/>{< br/> char chbuf [bufsize]; <br/> DWORD dwread, dwwritten; <br/> handle hstdin, hstdout; <br/> bool bsuccess; </P> <p> hstdout = getstdhandle (std_output_handle ); <br/> hstdin = getstdhandle (std_input_handle); <br/> If (<br/> (hstdout ==invalid_handle_value) | <br/> (hstdin = invalid_handle_value) <B R/>) <br/> exitprocess (1); </P> <p> // send something to this process's stdout using printf. <br/> printf ("/n ** this is a message from the child process. **/N "); <br/> // This simple algorithm uses the existence of the pipes to control execution. <br/> // it relies on the pipe buffers to ensure that no data is lost. <br/> // larger applications wocould use more advanced process control. <br/> (;) <Br/>{< br/> // read from standard input and stop on error or no data. <br/> bsuccess = readfile (hstdin, chbuf, bufsize, & dwread, null); </P> <p> If (! Bsuccess | dwread = 0) <br/> break; </P> <p> // write to standard output and stop on error. <br/> bsuccess = writefile (hstdout, chbuf, dwread, & dwwritten, null); </P> <p> If (! Bsuccess) <br/> break; <br/>}< br/> return 0; <br/>}< br/>

 

 

 

Http://msdn.microsoft.com/zh-cn/library/ms682499.aspx

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.