// @environmentOverride overrides even the global override values public static ProcessWrapper StartProcess (ProcessStartInfo startInfo, ProcessEventHandler outputStreamChanged, ProcessEventHandler errorStreamChanged, EventHandler exited, StringDictionary 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; }
protected virtual int ExecuteTool(string pathToTool, string responseFileCommands, string commandLineCommands) { if (pathToTool == null) { throw new ArgumentNullException("pathToTool"); } string responseFileName; responseFileName = null; toolOutput = new StringBuilder(); try { string responseFileSwitch = String.Empty; if (!String.IsNullOrEmpty(responseFileCommands)) { responseFileName = Path.GetTempFileName(); File.WriteAllText(responseFileName, responseFileCommands); responseFileSwitch = GetResponseFileSwitch(responseFileName); } var pinfo = GetProcessStartInfo(pathToTool, commandLineCommands, responseFileSwitch); LogToolCommand(String.Format("Tool {0} execution started with arguments: {1} {2}", pinfo.FileName, commandLineCommands, responseFileCommands)); var pendingLineFragmentOutput = new StringBuilder(); var pendingLineFragmentError = new StringBuilder(); var environmentOverride = GetAndLogEnvironmentVariables(); try { // When StartProcess returns, the process has already .Start()'ed // If we subscribe to the events after that, then for processes that // finish executing before we can subscribe, we won't get the output/err // events at all! ProcessWrapper pw = ProcessService.StartProcess(pinfo, (_, msg) => ProcessLine(pendingLineFragmentOutput, msg, StandardOutputLoggingImportance), (_, msg) => ProcessLine(pendingLineFragmentError, msg, StandardErrorLoggingImportance), null, environmentOverride); pw.WaitForOutput(timeout == Int32.MaxValue ? Int32.MaxValue : timeout); // Process any remaining line ProcessLine(pendingLineFragmentOutput, StandardOutputLoggingImportance, true); ProcessLine(pendingLineFragmentError, StandardErrorLoggingImportance, true); exitCode = pw.ExitCode; pw.Dispose(); } catch (System.ComponentModel.Win32Exception e) { Log.LogError("Error executing tool '{0}': {1}", pathToTool, e.Message); return(-1); } if (typeLoadException) { ProcessTypeLoadException(); } pendingLineFragmentOutput.Length = 0; pendingLineFragmentError.Length = 0; Log.LogMessage(MessageImportance.Low, "Tool {0} execution finished.", pathToTool); return(exitCode); } finally { DeleteTempFile(responseFileName); } }
protected virtual int ExecuteTool(string pathToTool, string responseFileCommands, string commandLineCommands) { if (pathToTool == null) { throw new ArgumentNullException("pathToTool"); } string output, error, responseFileName; StreamWriter outwr, errwr; outwr = errwr = null; responseFileName = output = error = null; toolOutput = new StringBuilder(); try { string arguments = commandLineCommands; if (!String.IsNullOrEmpty(responseFileCommands)) { responseFileName = Path.GetTempFileName(); File.WriteAllText(responseFileName, responseFileCommands); arguments = arguments + " " + GetResponseFileSwitch(responseFileName); } LogToolCommand(String.Format("Tool {0} execution started with arguments: {1} {2}", pathToTool, commandLineCommands, responseFileCommands)); output = Path.GetTempFileName(); error = Path.GetTempFileName(); outwr = new StreamWriter(output); errwr = new StreamWriter(error); ProcessStartInfo pinfo = new ProcessStartInfo(pathToTool, arguments); pinfo.WorkingDirectory = GetWorkingDirectory() ?? Environment.CurrentDirectory; pinfo.UseShellExecute = false; pinfo.RedirectStandardOutput = true; pinfo.RedirectStandardError = true; try { ProcessWrapper pw = ProcessService.StartProcess(pinfo, outwr, errwr, null, environmentOverride); pw.WaitForOutput(timeout == Int32.MaxValue ? -1 : timeout); exitCode = pw.ExitCode; outwr.Close(); errwr.Close(); pw.Dispose(); } catch (System.ComponentModel.Win32Exception e) { Log.LogError("Error executing tool '{0}': {1}", pathToTool, e.Message); return(-1); } ProcessOutputFile(output, StandardOutputLoggingImportance); ProcessOutputFile(error, StandardErrorLoggingImportance); Log.LogMessage(MessageImportance.Low, "Tool {0} execution finished.", pathToTool); return(exitCode); } finally { DeleteTempFile(responseFileName); if (outwr != null) { outwr.Dispose(); } if (errwr != null) { errwr.Dispose(); } DeleteTempFile(output); DeleteTempFile(error); } }