using System; using System.Collections.Generic; using System.Diagnostics; namespace Semmle.Util { public static class ProcessStartInfoExtensions { /// /// Runs this process, and returns the exit code, as well as the contents /// of stdout in . /// public static int ReadOutput(this ProcessStartInfo pi, out IList stdout, Action? onOut, Action? onError) { var @out = new List(); using var process = new Process { StartInfo = pi }; if (process.StartInfo.RedirectStandardOutput && !pi.UseShellExecute) { process.OutputDataReceived += new DataReceivedEventHandler((sender, e) => { if (e.Data == null) { return; } onOut?.Invoke(e.Data); @out.Add(e.Data); }); } if (process.StartInfo.RedirectStandardError && !pi.UseShellExecute) { process.ErrorDataReceived += new DataReceivedEventHandler((sender, e) => { if (e.Data == null) { return; } onError?.Invoke(e.Data); }); } process.Start(); if (process.StartInfo.RedirectStandardError) { process.BeginErrorReadLine(); } if (process.StartInfo.RedirectStandardOutput) { process.BeginOutputReadLine(); } process.WaitForExit(); stdout = @out; return process.ExitCode; } } }