/*
* 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();
}
}
}
}