5 using System.Collections;
6 using System.Collections.Specialized;
7 using System.Diagnostics;
9 using SCS = System.Collections.Specialized;
11 namespace Microsoft.Build.Utilities
13 internal static class ProcessService {
14 static SCS.ProcessStringDictionary globalEnvironmentVariablesOverride;
16 public static StringDictionary GlobalEnvironmentVariblesOverride {
18 if (globalEnvironmentVariablesOverride == null)
19 globalEnvironmentVariablesOverride = new SCS.ProcessStringDictionary ();
20 return globalEnvironmentVariablesOverride;
24 public static ProcessWrapper StartProcess (string command, string arguments, string workingDirectory, EventHandler exited)
26 return StartProcess (command, arguments, workingDirectory, (ProcessEventHandler)null, (ProcessEventHandler)null, exited);
29 public static ProcessWrapper StartProcess (string command, string arguments, string workingDirectory, ProcessEventHandler outputStreamChanged, ProcessEventHandler errorStreamChanged)
31 return StartProcess (command, arguments, workingDirectory, outputStreamChanged, errorStreamChanged, null);
34 public static ProcessWrapper StartProcess (string command, string arguments, string workingDirectory, TextWriter outWriter, TextWriter errorWriter, EventHandler exited)
36 return StartProcess (command, arguments, workingDirectory, outWriter, errorWriter, exited, false);
39 public static ProcessWrapper StartProcess (string command, string arguments, string workingDirectory, TextWriter outWriter, TextWriter errorWriter, EventHandler exited, bool redirectStandardInput)
41 ProcessEventHandler wout = OutWriter.GetWriteHandler (outWriter);
42 ProcessEventHandler werr = OutWriter.GetWriteHandler (errorWriter);
43 return StartProcess (command, arguments, workingDirectory, wout, werr, exited, redirectStandardInput);
46 public static ProcessWrapper StartProcess (string command, string arguments, string workingDirectory, ProcessEventHandler outputStreamChanged, ProcessEventHandler errorStreamChanged, EventHandler exited)
48 return StartProcess (command, arguments, workingDirectory, outputStreamChanged, errorStreamChanged, exited, false);
51 public static ProcessWrapper StartProcess (string command, string arguments, string workingDirectory, ProcessEventHandler outputStreamChanged, ProcessEventHandler errorStreamChanged, EventHandler exited, bool redirectStandardInput)
53 return StartProcess (CreateProcessStartInfo (command, arguments, workingDirectory, redirectStandardInput),
54 outputStreamChanged, errorStreamChanged, exited, null);
57 public static ProcessWrapper StartProcess (ProcessStartInfo startInfo, TextWriter outWriter, TextWriter errorWriter, EventHandler exited)
59 return StartProcess (startInfo, outWriter, errorWriter, exited, null);
62 public static ProcessWrapper StartProcess (ProcessStartInfo startInfo, TextWriter outWriter, TextWriter errorWriter, EventHandler exited, StringDictionary environmentOverride)
64 ProcessEventHandler wout = OutWriter.GetWriteHandler (outWriter);
65 ProcessEventHandler werr = OutWriter.GetWriteHandler (errorWriter);
66 return StartProcess (startInfo, wout, werr, exited, environmentOverride);
69 // @environmentOverride overrides even the global override values
70 public static ProcessWrapper StartProcess (ProcessStartInfo startInfo, ProcessEventHandler outputStreamChanged, ProcessEventHandler errorStreamChanged, EventHandler exited, StringDictionary environmentOverride)
72 if (startInfo == null)
73 throw new ArgumentException ("startInfo");
75 ProcessWrapper p = new ProcessWrapper();
77 if (outputStreamChanged != null) {
78 p.OutputStreamChanged += outputStreamChanged;
81 if (errorStreamChanged != null)
82 p.ErrorStreamChanged += errorStreamChanged;
87 p.StartInfo = startInfo;
88 ProcessEnvironmentVariableOverrides (p.StartInfo, environmentOverride);
90 // WORKAROUND for "Bug 410743 - wapi leak in System.Diagnostic.Process"
91 // Process leaks when an exit event is registered
92 // instead we use another thread to monitor I/O and wait for exit
93 // p.EnableRaisingEvents = true;
99 public static ProcessStartInfo CreateProcessStartInfo (string command, string arguments, string workingDirectory, bool redirectStandardInput)
102 throw new ArgumentNullException("command");
104 if (command.Length == 0)
105 throw new ArgumentException("command");
107 ProcessStartInfo startInfo = null;
108 if(String.IsNullOrEmpty (arguments))
109 startInfo = new ProcessStartInfo (command);
111 startInfo = new ProcessStartInfo (command, arguments);
113 if(workingDirectory != null && workingDirectory.Length > 0)
114 startInfo.WorkingDirectory = workingDirectory;
116 startInfo.RedirectStandardOutput = true;
117 startInfo.RedirectStandardError = true;
118 startInfo.RedirectStandardInput = redirectStandardInput;
119 startInfo.UseShellExecute = false;
120 startInfo.CreateNoWindow = true;
125 public static void ProcessEnvironmentVariableOverrides (ProcessStartInfo info, StringDictionary environmentOverride)
127 if (globalEnvironmentVariablesOverride != null)
128 foreach (DictionaryEntry entry in globalEnvironmentVariablesOverride)
129 ProcessEnvironmentVariable (info, (string)entry.Key, (string)entry.Value);
131 if (environmentOverride != null)
132 foreach (DictionaryEntry entry in environmentOverride)
133 ProcessEnvironmentVariable (info, (string)entry.Key, (string)entry.Value);
136 static void ProcessEnvironmentVariable (ProcessStartInfo info, string name, string value)
138 if (value == null && info.EnvironmentVariables.ContainsKey (name))
139 info.EnvironmentVariables.Remove (name);
141 info.EnvironmentVariables[name] = value;
150 public OutWriter (TextWriter writer)
152 this.writer = writer;
155 public void WriteOut (object sender, string s)
160 public static ProcessEventHandler GetWriteHandler (TextWriter tw)
162 return tw != null ? new ProcessEventHandler(new OutWriter (tw).WriteOut) : null;