Often see someone in the forum asks how to get its output issues after starting new processes with Process components. Take the output of the sub-process into a temporary file, of course, can also solve the problem. However, after each parent process acquires information from the temporary file, it is more troublesome to delete the temporary file. In fact, Process provides several properties to get the output. There is an example in this area in the help document of the .NET Framework SDK, but the specific code is not given to how to obtain the error output and the standard output, this article will give an instance and some instructions on the characteristics of the pipe.
I. Get a child process standard output and error output: We write a small program P2.cs, use it to generate standard output and error output. //p2.cs code as follows: use system; class class1 {public static void main () {int i = 0; string s1 = string.format ("OUT: {0, 4} --------- ---------------------------------------- ", i); system.console. Out.writeline (S1); String S2 = String.Format ("Err: {0, 4} ************************************ *********************** ", i); system.console.error.writeline (S2);}} compiled into p2.exe
Get the standard output of the child process and the source program //p1.cs....process p = new process ("p2.exe"); p.StartInfo.uShellexecute = false; / / Specify the outer casing without using the system The program, but directly starts the called program itself P.StartInfo.RedirectStandardoutput = true; // Only use this property to True to obtain the child process output by the pipeline to output P.StartInfo.redirectStanderror = true;
p.Start (); // Inns Script Output = P.standardOutput.ReadToEnd (); // Read standard output string error = p.standarderror.readToEnd (); // Read error Output p.WaitForexit () Waiting for the sub-process execution ... In the above example, after the parent process starts the sub-process, wait for the standard output from the pipeline, and take the error output after removing all the standard outputs. We have no mistakes running. But once I increase the number of bytes of standard output and error output in p2.exe: for (i = 0; i <200; i ) system.console.out.writeline (S1); for (i = 0; i <200; i ) System.console.Error.writeline (S2); After compiling, run again, then find that the parent process and sub-process have a deadlock, only forgively turning it to terminate the process.
Second, the pipeline: The Process component communicates with the sub-process through the pipeline. If you are redirecting standard output and standard errors, try to read them, there will be problems when the pipe is filled. In the above example, the parent process only reads all the standard outputs to read the error output, while the child process will take the pipeline, the parent process will take away, the child process then outputs subsequent standard outputs to the pipeline. This is very good. However, when the child process executes an output error output, because the sub-process has not run end, its standard output stream will not be in the end state (although the standard output of its 200 cycles in our example is already executed) This causes the readtoend () method in the parent process, so that P.Standarderror.ReadToeend () in the parent process cannot be executed, so that the error output in the pipe cannot be read, the subsequent subsequent error output cannot be Write the pipeline, the final child process and the parent process are unlimited to each other, and blocking conditions have occurred. The child process determines whether to output a follow-up content by checking whether the last byte in the pipe is taken. That is, if all the content before the last byte in the pipe buffer is taken away, the child process will still be waiting; if all bytes before, but the last byte content is taken away, The sub-process will continue to output subsequent content to the pipeline, of course, can only output one byte to the last position in the pipe. If we change the string output = p.standardoutput.readtore () in p1.cs: for (int i = 0; i <200 * 60; i ) console.write ((char) p.standardoutput.read () There will be no deadlocks. Because after the loop execution of the acquisition of the standard output, the statement that acquires the error output is then performed without waiting for the end of the standard output stream. However, this method has no practical significance, because in practice, we cannot know how many bytes will be known in this case.