private System.Diagnostics.Process CreateProcess(ProcessSpec processSpec) { var process = new System.Diagnostics.Process { EnableRaisingEvents = true, StartInfo = { FileName = processSpec.Executable, // Arguments = ArgumentEscaper.EscapeAndConcatenateArgArrayForProcessStart(processSpec.Arguments), Arguments = ArgumentEscaper.EscapeAndConcatenateArgArrayForProcessStart(processSpec.Arguments), UseShellExecute = false, WorkingDirectory = processSpec.WorkingDirectory, RedirectStandardOutput = processSpec.IsOutputCaptured || (processSpec.OnOutput != null), RedirectStandardError = processSpec.IsOutputCaptured, } }; foreach (var env in processSpec.EnvironmentVariables) { process.StartInfo.Environment.Add(env.Key, env.Value); } return(process); }
// May not be necessary in the future. See https://github.com/dotnet/corefx/issues/12039 public async Task <int> RunAsync(ProcessSpec processSpec, CancellationToken cancellationToken) { Ensure.NotNull(processSpec, nameof(processSpec)); int exitCode; var stopwatch = new Stopwatch(); using (var process = CreateProcess(processSpec)) using (var processState = new ProcessState(process, _reporter)) { cancellationToken.Register(() => processState.TryKill()); var readOutput = false; var readError = false; if (processSpec.IsOutputCaptured) { readOutput = true; readError = true; process.OutputDataReceived += (_, a) => { if (!string.IsNullOrEmpty(a.Data)) { processSpec.OutputCapture.AddLine(a.Data); } }; process.ErrorDataReceived += (_, a) => { if (!string.IsNullOrEmpty(a.Data)) { processSpec.OutputCapture.AddLine(a.Data); } }; } else if (processSpec.OnOutput != null) { readOutput = true; process.OutputDataReceived += processSpec.OnOutput; } stopwatch.Start(); process.Start(); _reporter.Verbose($"Started '{processSpec.Executable}' '{process.StartInfo.Arguments}' with process id {process.Id}"); if (readOutput) { process.BeginOutputReadLine(); } if (readError) { process.BeginErrorReadLine(); } await processState.Task; exitCode = process.ExitCode; stopwatch.Stop(); _reporter.Verbose($"Process id {process.Id} ran for {stopwatch.ElapsedMilliseconds}ms"); } return(exitCode); }
public Task <int> RunAsync(ProcessSpec processSpec) { var processRunner = new ProcessRunner(_reporter); return(processRunner.RunAsync(processSpec, _cts.Token)); }