/// <summary> /// use this one if you're doing a long running task that you'll have running in a thread, so that you need a way to abort it /// </summary> public ExecutionResult Start(string exePath, string arguments, Encoding encoding, string fromDirectory, int secondsBeforeTimeOut, IProgress progress, Action<string> actionForReportingProgress, string standardInputPath = null) { progress.WriteVerbose("running '{0} {1}' from '{2}'", exePath, arguments, fromDirectory); ExecutionResult result = new ExecutionResult(); result.Arguments = arguments; result.ExePath = exePath; using (_process = new Process()) { _process.StartInfo.RedirectStandardError = true; _process.StartInfo.RedirectStandardOutput = true; _process.StartInfo.UseShellExecute = false; _process.StartInfo.CreateNoWindow = true; _process.StartInfo.WorkingDirectory = fromDirectory; _process.StartInfo.FileName = exePath; _process.StartInfo.Arguments = arguments; if (encoding != null) { _process.StartInfo.StandardOutputEncoding = encoding; } if (actionForReportingProgress != null) _processReader = new AsyncProcessOutputReader(_process, progress, actionForReportingProgress); else _processReader = new SynchronousProcessOutputReader(_process, progress); if (standardInputPath != null) _process.StartInfo.RedirectStandardInput = true; try { Debug.WriteLine("CommandLineRunner Starting at " + DateTime.Now.ToString()); _process.Start(); if (standardInputPath != null) { var myWriter = _process.StandardInput.BaseStream; var input = File.ReadAllBytes(standardInputPath); myWriter.Write(input, 0, input.Length); myWriter.Close(); // no more input } } catch (Win32Exception error) { throw; } if (secondsBeforeTimeOut > TimeoutSecondsOverrideForUnitTests) secondsBeforeTimeOut = TimeoutSecondsOverrideForUnitTests; bool timedOut = false; Debug.WriteLine("CommandLineRunner Reading at " + DateTime.Now.ToString("HH:mm:ss.ffff")); if (!_processReader.Read(secondsBeforeTimeOut)) { timedOut = !progress.CancelRequested; try { if (_process.HasExited) { progress.WriteWarning("Process exited, cancelRequested was {0}", progress.CancelRequested); } else { if (timedOut) progress.WriteWarning("({0}) Timed Out...", exePath); progress.WriteWarning("Killing Process ({0})", exePath); _process.Kill(); } } catch (Exception e) { progress.WriteWarning( "Exception while killing process, as though the process reader failed to notice that the process was over: {0}", e.Message); progress.WriteWarning("Process.HasExited={0}", _process.HasExited.ToString()); } } result.StandardOutput = _processReader.StandardOutput; result.StandardError = _processReader.StandardError; if (timedOut) { result.StandardError += Environment.NewLine + "Timed Out after waiting " + secondsBeforeTimeOut + " seconds."; result.ExitCode = ExecutionResult.kTimedOut; } else if (progress.CancelRequested) { result.StandardError += Environment.NewLine + "User Cancelled."; result.ExitCode = ExecutionResult.kCancelled; } else { result.ExitCode = _process.ExitCode; } } return result; }
/// <summary> /// use this one if you're doing a long running task that you'll have running in a thread, so that you need a way to abort it /// </summary> public ExecutionResult Start(string exePath, string arguments, Encoding encoding, string fromDirectory, int secondsBeforeTimeOut, IProgress progress, Action <string> actionForReportingProgress, string standardInputPath = null) { progress.WriteVerbose("running '{0} {1}' from '{2}'", exePath, arguments, fromDirectory); ExecutionResult result = new ExecutionResult(); result.Arguments = arguments; result.ExePath = exePath; using (_process = new Process()) { _process.StartInfo.RedirectStandardError = true; _process.StartInfo.RedirectStandardOutput = true; _process.StartInfo.UseShellExecute = false; _process.StartInfo.CreateNoWindow = true; _process.StartInfo.WorkingDirectory = fromDirectory; _process.StartInfo.FileName = exePath; _process.StartInfo.Arguments = arguments; if (encoding != null) { _process.StartInfo.StandardOutputEncoding = encoding; } if (actionForReportingProgress != null) { _processReader = new AsyncProcessOutputReader(_process, progress, actionForReportingProgress); } else { _processReader = new SynchronousProcessOutputReader(_process, progress); } if (standardInputPath != null) { _process.StartInfo.RedirectStandardInput = true; } try { Debug.WriteLine("CommandLineRunner Starting at " + DateTime.Now.ToString()); _process.Start(); if (standardInputPath != null) { var myWriter = _process.StandardInput.BaseStream; var input = File.ReadAllBytes(standardInputPath); myWriter.Write(input, 0, input.Length); myWriter.Close(); // no more input } } catch (Win32Exception error) { throw; } if (secondsBeforeTimeOut > TimeoutSecondsOverrideForUnitTests) { secondsBeforeTimeOut = TimeoutSecondsOverrideForUnitTests; } bool timedOut = false; Debug.WriteLine("CommandLineRunner Reading at " + DateTime.Now.ToString("HH:mm:ss.ffff")); if (!_processReader.Read(secondsBeforeTimeOut)) { timedOut = !progress.CancelRequested; try { if (_process.HasExited) { progress.WriteWarning("Process exited, cancelRequested was {0}", progress.CancelRequested); } else { if (timedOut) { progress.WriteWarning("({0}) Timed Out...", exePath); } progress.WriteWarning("Killing Process ({0})", exePath); _process.Kill(); } } catch (Exception e) { progress.WriteWarning( "Exception while killing process, as though the process reader failed to notice that the process was over: {0}", e.Message); progress.WriteWarning("Process.HasExited={0}", _process.HasExited.ToString()); } } result.StandardOutput = _processReader.StandardOutput; result.StandardError = _processReader.StandardError; if (timedOut) { result.StandardError += Environment.NewLine + "Timed Out after waiting " + secondsBeforeTimeOut + " seconds."; result.ExitCode = ExecutionResult.kTimedOut; } else if (progress.CancelRequested) { result.StandardError += Environment.NewLine + "User Cancelled."; result.ExitCode = ExecutionResult.kCancelled; } else { result.ExitCode = _process.ExitCode; } } return(result); }