1 // created on 12/18/2004 at 16:28
3 using System.Threading;
4 using System.Diagnostics;
6 namespace Microsoft.Build.Utilities
8 internal delegate void ProcessEventHandler(object sender, string message);
10 internal class ProcessWrapper : Process, IProcessAsyncOperation
12 ManualResetEvent endEventOut = new ManualResetEvent (false);
13 ManualResetEvent endEventErr = new ManualResetEvent (false);
14 ManualResetEvent endEventExit = new ManualResetEvent (false);
16 object lockObj = new object ();
18 public ProcessWrapper ()
22 public new void Start ()
26 base.EnableRaisingEvents = true;
28 base.Exited += (s, args) => {
31 WaitHandle.WaitAll (new WaitHandle[] { endEventOut, endEventErr });
32 OnExited (this, EventArgs.Empty);
35 base.OutputDataReceived += (s, args) => {
36 if (args.Data == null) {
39 ProcessEventHandler handler = OutputStreamChanged;
41 handler (this, args.Data);
45 base.ErrorDataReceived += (s, args) => {
46 if (args.Data == null) {
49 ProcessEventHandler handler = ErrorStreamChanged;
51 handler (this, args.Data);
57 base.BeginOutputReadLine ();
58 base.BeginErrorReadLine ();
61 public void WaitForOutput (int milliseconds)
64 WaitHandle.WaitAll (new WaitHandle[] { endEventOut, endEventErr, endEventExit }, milliseconds);
67 public void WaitForOutput ()
72 protected override void Dispose (bool disposing)
75 if (endEventOut == null)
80 ((IAsyncOperation)this).Cancel ();
84 endEventExit.Close ();
86 base.Dispose (disposing);
91 if (endEventOut == null)
92 throw new ObjectDisposedException ("ProcessWrapper");
95 int IProcessAsyncOperation.ExitCode {
96 get { return ExitCode; }
99 int IProcessAsyncOperation.ProcessId {
103 void IAsyncOperation.Cancel ()
113 base.CancelOutputRead ();
114 } catch (InvalidOperationException) {
115 // Ignore: might happen if Start wasn't called
118 base.CancelErrorRead ();
119 } catch (InvalidOperationException) {
120 // Ignore: might happen if Start wasn't called
123 } catch (Exception ex) {
125 Console.WriteLine (ex.ToString ());
126 //LoggingService.LogError (ex.ToString ());
130 void IAsyncOperation.WaitForCompleted ()
135 void OnExited (object sender, EventArgs args)
140 OperationHandler handler = completedEvent;
149 event OperationHandler IAsyncOperation.Completed {
151 bool raiseNow = false;
156 completedEvent += value;
163 completedEvent -= value;
168 bool IAsyncOperation.Success {
169 get { return done ? ExitCode == 0 : false; }
172 bool IAsyncOperation.SuccessWithWarnings {
173 get { return false; }
176 bool IAsyncOperation.IsCompleted {
180 event OperationHandler completedEvent;
182 public event ProcessEventHandler OutputStreamChanged;
183 public event ProcessEventHandler ErrorStreamChanged;