public static ShellProcess Start(ShellProcessArguments args) { var startInfo = new ProcessStartInfo() { FileName = args.Executable, Arguments = string.Join(" ", args.Arguments), WorkingDirectory = args.WorkingDirectory?.FullName ?? new DirectoryInfo(".").FullName, RedirectStandardInput = true, RedirectStandardOutput = true, StandardOutputEncoding = Encoding.UTF8, RedirectStandardError = true, StandardErrorEncoding = Encoding.UTF8, CreateNoWindow = true, UseShellExecute = false }; if (args.EnvironmentVariables != null) { foreach (var pair in args.EnvironmentVariables) { startInfo.EnvironmentVariables[pair.Key] = pair.Value; } } var shellProcess = new ShellProcess(startInfo); shellProcess.Process.OutputDataReceived += (sender, data) => { shellProcess.TimeOfLastObservedOutput = DateTime.Now; args.OutputDataReceived?.Invoke(sender, data); }; shellProcess.Process.ErrorDataReceived += (sender, data) => { shellProcess.TimeOfLastObservedOutput = DateTime.Now; args.ErrorDataReceived?.Invoke(sender, data); }; shellProcess.Process.Start(); shellProcess.Process.BeginOutputReadLine(); shellProcess.Process.BeginErrorReadLine(); return(shellProcess); }
public static ShellProcessOutput Run(ShellProcessArguments shellArgs) { Assert.IsNotNull(shellArgs); Assert.IsFalse(string.IsNullOrEmpty(shellArgs.Executable)); var runOutput = new ShellProcessOutput(); var hasErrors = false; var output = new StringBuilder(); var logOutput = new StringBuilder(); var errorOutput = new StringBuilder(); // Prepare data received handlers DataReceivedEventHandler outputReceived = (sender, e) => { LogProcessData(e.Data, output); logOutput.AppendLine(e.Data); }; DataReceivedEventHandler errorReceived = (sender, e) => { if (!string.IsNullOrEmpty(e.Data)) { errorOutput.AppendLine(e.Data); if (shellArgs.AnyOutputToErrorIsAnError) { hasErrors = true; } } LogProcessData(e.Data, output); logOutput.AppendLine(e.Data); }; // Run command in shell and wait for exit var process = Start(new ShellProcessArguments { Executable = shellArgs.Executable, Arguments = shellArgs.Arguments, EnvironmentVariables = shellArgs.EnvironmentVariables, WorkingDirectory = shellArgs.WorkingDirectory, OutputDataReceived = outputReceived, ErrorDataReceived = errorReceived }); var processUpdate = process.WaitForProcess(shellArgs.MaxIdleTimeInMilliseconds); while (processUpdate.MoveNext()) { } var exitCode = process.Process.ExitCode; if (processUpdate.Current == ProcessStatus.Killed) { exitCode = shellArgs.MaxIdleKillIsAnError ? -1 : 0; } runOutput.ExitCode = exitCode; runOutput.Command = shellArgs.Executable; runOutput.CommandOutput = output; runOutput.FullOutput = logOutput.ToString(); runOutput.ErrorOutput = errorOutput.ToString(); LogProcessData($"Process exited with code '{exitCode}'", logOutput); hasErrors |= (exitCode != 0); if (hasErrors && shellArgs.ThrowOnError) { throw new Exception(errorOutput.ToString()); } runOutput.Succeeded = !hasErrors; return(runOutput); }