/* * When using the ProcessStartInfo.RedirectStandardXxx properties there is a chance of * the parent and child process blocking due to a race condition. This class handles the * problem. * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemdiagnosticsprocessstartinfoclassredirectstandardoutputtopic.asp */ using System; using System.IO; using System.Threading; using System.Diagnostics; namespace ReactOS.CustomRevisionAction { /// /// Process that redirects standard output and standard error streams. /// public class RedirectableProcess { /// /// Process. /// private Process process; /// /// Redirected standard error stream. /// private string processError; /// /// Redirected standard output stream. /// private string processOutput; /// /// Exit code. /// private int exitCode; /// /// Redirected standard error stream. /// public string ProcessError { get { return processError; } } /// /// Redirected standard output stream. /// public string ProcessOutput { get { return processOutput; } } /// /// Exit code. /// public int ExitCode { get { return exitCode; } } /// /// Run an excutable and redirect standard error and/or standard output safely. /// public RedirectableProcess(ProcessStartInfo processStartInfo) { Run(processStartInfo, null); } /// /// Run an excutable and redirect standard error and/or standard output safely. /// public RedirectableProcess(ProcessStartInfo processStartInfo, string input) { Run(processStartInfo, input); } private void Run(ProcessStartInfo processStartInfo, string input) { process = new Process(); process.StartInfo = processStartInfo; process.Start(); if (processStartInfo.RedirectStandardInput && input != null) { process.StandardInput.AutoFlush = true; process.StandardInput.WriteLine(input); } Thread readStandardError = null; if (processStartInfo.RedirectStandardError) { readStandardError = new Thread(new ThreadStart(ReadStandardError)); readStandardError.Start(); } Thread readStandardOutput = null; if (processStartInfo.RedirectStandardOutput) { readStandardOutput = new Thread(new ThreadStart(ReadStandardOutput)); readStandardOutput.Start(); } if (processStartInfo.RedirectStandardError) { readStandardError.Join(); } if (processStartInfo.RedirectStandardOutput) { readStandardOutput.Join(); } process.WaitForExit(); exitCode = process.ExitCode; process = null; } /// /// Read standard error thread entry-point. /// private void ReadStandardError() { if (process != null) { processError = process.StandardError.ReadToEnd(); } } /// /// Read standard output thread entry-point. /// private void ReadStandardOutput() { if (process != null) { processOutput = process.StandardOutput.ReadToEnd(); } } } }