Jo Shields 3c1f479b9d Imported Upstream version 4.0.0~alpha1
Former-commit-id: 806294f5ded97629b74c85c09952f2a74fe182d9
2015-04-07 09:35:12 +01:00

164 lines
6.1 KiB
C#

using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
namespace Microsoft.Build.Utilities
{
internal static class ProcessService {
static Dictionary<string, string> globalEnvironmentVariablesOverride;
public static Dictionary<string, string> GlobalEnvironmentVariblesOverride {
get {
if (globalEnvironmentVariablesOverride == null)
globalEnvironmentVariablesOverride = new Dictionary<string, string> (StringComparer.InvariantCultureIgnoreCase);
return globalEnvironmentVariablesOverride;
}
}
public static ProcessWrapper StartProcess (string command, string arguments, string workingDirectory, EventHandler exited)
{
return StartProcess (command, arguments, workingDirectory, (ProcessEventHandler)null, (ProcessEventHandler)null, exited);
}
public static ProcessWrapper StartProcess (string command, string arguments, string workingDirectory, ProcessEventHandler outputStreamChanged, ProcessEventHandler errorStreamChanged)
{
return StartProcess (command, arguments, workingDirectory, outputStreamChanged, errorStreamChanged, null);
}
public static ProcessWrapper StartProcess (string command, string arguments, string workingDirectory, TextWriter outWriter, TextWriter errorWriter, EventHandler exited)
{
return StartProcess (command, arguments, workingDirectory, outWriter, errorWriter, exited, false);
}
public static ProcessWrapper StartProcess (string command, string arguments, string workingDirectory, TextWriter outWriter, TextWriter errorWriter, EventHandler exited, bool redirectStandardInput)
{
ProcessEventHandler wout = OutWriter.GetWriteHandler (outWriter);
ProcessEventHandler werr = OutWriter.GetWriteHandler (errorWriter);
return StartProcess (command, arguments, workingDirectory, wout, werr, exited, redirectStandardInput);
}
public static ProcessWrapper StartProcess (string command, string arguments, string workingDirectory, ProcessEventHandler outputStreamChanged, ProcessEventHandler errorStreamChanged, EventHandler exited)
{
return StartProcess (command, arguments, workingDirectory, outputStreamChanged, errorStreamChanged, exited, false);
}
public static ProcessWrapper StartProcess (string command, string arguments, string workingDirectory, ProcessEventHandler outputStreamChanged, ProcessEventHandler errorStreamChanged, EventHandler exited, bool redirectStandardInput)
{
return StartProcess (CreateProcessStartInfo (command, arguments, workingDirectory, redirectStandardInput),
outputStreamChanged, errorStreamChanged, exited, null);
}
public static ProcessWrapper StartProcess (ProcessStartInfo startInfo, TextWriter outWriter, TextWriter errorWriter, EventHandler exited)
{
return StartProcess (startInfo, outWriter, errorWriter, exited, null);
}
public static ProcessWrapper StartProcess (ProcessStartInfo startInfo, TextWriter outWriter, TextWriter errorWriter, EventHandler exited, Dictionary<string, string> environmentOverride)
{
ProcessEventHandler wout = OutWriter.GetWriteHandler (outWriter);
ProcessEventHandler werr = OutWriter.GetWriteHandler (errorWriter);
return StartProcess (startInfo, wout, werr, exited, environmentOverride);
}
// @environmentOverride overrides even the global override values
public static ProcessWrapper StartProcess (ProcessStartInfo startInfo, ProcessEventHandler outputStreamChanged, ProcessEventHandler errorStreamChanged, EventHandler exited, Dictionary<string, string> environmentOverride)
{
if (startInfo == null)
throw new ArgumentException ("startInfo");
ProcessWrapper p = new ProcessWrapper();
if (outputStreamChanged != null) {
p.OutputStreamChanged += outputStreamChanged;
}
if (errorStreamChanged != null)
p.ErrorStreamChanged += errorStreamChanged;
if (exited != null)
p.Exited += exited;
p.StartInfo = startInfo;
ProcessEnvironmentVariableOverrides (p.StartInfo, environmentOverride);
// WORKAROUND for "Bug 410743 - wapi leak in System.Diagnostic.Process"
// Process leaks when an exit event is registered
// instead we use another thread to monitor I/O and wait for exit
// p.EnableRaisingEvents = true;
p.Start ();
return p;
}
public static ProcessStartInfo CreateProcessStartInfo (string command, string arguments, string workingDirectory, bool redirectStandardInput)
{
if (command == null)
throw new ArgumentNullException("command");
if (command.Length == 0)
throw new ArgumentException("command");
ProcessStartInfo startInfo = null;
if(String.IsNullOrEmpty (arguments))
startInfo = new ProcessStartInfo (command);
else
startInfo = new ProcessStartInfo (command, arguments);
if(workingDirectory != null && workingDirectory.Length > 0)
startInfo.WorkingDirectory = workingDirectory;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
startInfo.RedirectStandardInput = redirectStandardInput;
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
return startInfo;
}
public static void ProcessEnvironmentVariableOverrides (ProcessStartInfo info, Dictionary<string, string> environmentOverride)
{
if (globalEnvironmentVariablesOverride != null)
foreach (var entry in globalEnvironmentVariablesOverride)
ProcessEnvironmentVariable (info, (string)entry.Key, (string)entry.Value);
if (environmentOverride != null)
foreach (var entry in environmentOverride)
ProcessEnvironmentVariable (info, (string)entry.Key, (string)entry.Value);
}
static void ProcessEnvironmentVariable (ProcessStartInfo info, string name, string value)
{
if (value == null && info.EnvironmentVariables.ContainsKey (name))
info.EnvironmentVariables.Remove (name);
else
info.EnvironmentVariables[name] = value;
}
}
class OutWriter
{
TextWriter writer;
public OutWriter (TextWriter writer)
{
this.writer = writer;
}
public void WriteOut (object sender, string s)
{
writer.Write (s);
}
public static ProcessEventHandler GetWriteHandler (TextWriter tw)
{
return tw != null ? new ProcessEventHandler(new OutWriter (tw).WriteOut) : null;
}
}
}