Minor cleanup of GetVolumeNameForVolumeMountPointW and fix some incorrect return...
[reactos.git] / cis / ReactOS.Verify / RedirectableProcess.cs
1 /*
2 * When using the ProcessStartInfo.RedirectStandardXxx properties there is a chance of
3 * the parent and child process blocking due to a race condition. This class handles the
4 * problem.
5 * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemdiagnosticsprocessstartinfoclassredirectstandardoutputtopic.asp
6 */
7 using System;
8 using System.IO;
9 using System.Threading;
10 using System.Diagnostics;
11
12 namespace ReactOS.Verify
13 {
14 /// <summary>
15 /// Process that redirects standard output and standard error streams.
16 /// </summary>
17 public class RedirectableProcess
18 {
19 /// <summary>
20 /// Process.
21 /// </summary>
22 private Process process;
23
24 /// <summary>
25 /// Redirected standard error stream.
26 /// </summary>
27 private string processError;
28
29 /// <summary>
30 /// Redirected standard output stream.
31 /// </summary>
32 private string processOutput;
33
34 /// <summary>
35 /// Exit code.
36 /// </summary>
37 private int exitCode;
38
39 /// <summary>
40 /// Redirected standard error stream.
41 /// </summary>
42 public string ProcessError
43 {
44 get
45 {
46 return processError;
47 }
48 }
49
50 /// <summary>
51 /// Redirected standard output stream.
52 /// </summary>
53 public string ProcessOutput
54 {
55 get
56 {
57 return processOutput;
58 }
59 }
60
61 /// <summary>
62 /// Exit code.
63 /// </summary>
64 public int ExitCode
65 {
66 get
67 {
68 return exitCode;
69 }
70 }
71
72 /// <summary>
73 /// Run an excutable and redirect standard error and/or standard output safely.
74 /// </summary>
75 public RedirectableProcess(ProcessStartInfo processStartInfo)
76 {
77 Run(processStartInfo, null);
78 }
79
80 /// <summary>
81 /// Run an excutable and redirect standard error and/or standard output safely.
82 /// </summary>
83 public RedirectableProcess(ProcessStartInfo processStartInfo, string input)
84 {
85 Run(processStartInfo, input);
86 }
87
88 private void Run(ProcessStartInfo processStartInfo, string input)
89 {
90 process = new Process();
91 process.StartInfo = processStartInfo;
92 process.Start();
93 if (processStartInfo.RedirectStandardInput && input != null)
94 {
95 process.StandardInput.AutoFlush = true;
96 process.StandardInput.WriteLine(input);
97 }
98 Thread readStandardError = null;
99 if (processStartInfo.RedirectStandardError)
100 {
101 readStandardError = new Thread(new ThreadStart(ReadStandardError));
102 readStandardError.Start();
103 }
104 Thread readStandardOutput = null;
105 if (processStartInfo.RedirectStandardOutput)
106 {
107 readStandardOutput = new Thread(new ThreadStart(ReadStandardOutput));
108 readStandardOutput.Start();
109 }
110 if (processStartInfo.RedirectStandardError)
111 {
112 readStandardError.Join();
113 }
114 if (processStartInfo.RedirectStandardOutput)
115 {
116 readStandardOutput.Join();
117 }
118 process.WaitForExit();
119 exitCode = process.ExitCode;
120 process = null;
121 }
122
123 /// <summary>
124 /// Read standard error thread entry-point.
125 /// </summary>
126 private void ReadStandardError()
127 {
128 if (process != null)
129 {
130 processError = process.StandardError.ReadToEnd();
131 }
132 }
133
134 /// <summary>
135 /// Read standard output thread entry-point.
136 /// </summary>
137 private void ReadStandardOutput()
138 {
139 if (process != null)
140 {
141 processOutput = process.StandardOutput.ReadToEnd();
142 }
143 }
144 }
145 }