public static DotNetCliCommandResult Execute(DotNetCliCommand parameters) { using (var process = new Process { StartInfo = BuildStartInfo(parameters.CliPath, parameters.GenerateResult.ArtifactsPaths.BuildArtifactsDirectoryPath, parameters.Arguments, parameters.EnvironmentVariables) }) using (var outputReader = new AsyncProcessOutputReader(process, parameters.LogOutput, parameters.Logger)) using (new ConsoleExitHandler(process, parameters.Logger)) { parameters.Logger.WriteLineInfo($"// start {parameters.CliPath ?? "dotnet"} {parameters.Arguments} in {parameters.GenerateResult.ArtifactsPaths.BuildArtifactsDirectoryPath}"); var stopwatch = Stopwatch.StartNew(); process.Start(); outputReader.BeginRead(); if (!process.WaitForExit((int)parameters.Timeout.TotalMilliseconds)) { parameters.Logger.WriteLineError($"// command took longer than the timeout: {parameters.Timeout.TotalSeconds:0.##}s. Killing the process tree!"); outputReader.CancelRead(); process.KillTree(); return(DotNetCliCommandResult.Failure(stopwatch.Elapsed, $"The configured timeout {parameters.Timeout} was reached!" + outputReader.GetErrorText(), outputReader.GetOutputText())); } stopwatch.Stop(); outputReader.StopRead(); parameters.Logger.WriteLineInfo($"// command took {stopwatch.Elapsed.TotalSeconds:0.##}s and exited with {process.ExitCode}"); return(process.ExitCode <= 0 ? DotNetCliCommandResult.Success(stopwatch.Elapsed, outputReader.GetOutputText()) : DotNetCliCommandResult.Failure(stopwatch.Elapsed, outputReader.GetOutputText(), outputReader.GetErrorText())); } }
public IEnumerable <string> ExportToFiles(Summary summary, ILogger consoleLogger) { const string scriptFileName = "BuildPlots.R"; const string logFileName = "BuildPlots.log"; yield return(Path.Combine(summary.ResultsDirectoryPath, scriptFileName)); string csvFullPath = CsvMeasurementsExporter.Default.GetArtifactFullName(summary); string scriptFullPath = Path.Combine(summary.ResultsDirectoryPath, scriptFileName); string logFullPath = Path.Combine(summary.ResultsDirectoryPath, logFileName); string script = ResourceHelper. LoadTemplate(scriptFileName). Replace("$BenchmarkDotNetVersion$", BenchmarkDotNetInfo.FullTitle). Replace("$CsvSeparator$", CsvMeasurementsExporter.Default.Separator); lock (BuildScriptLock) File.WriteAllText(scriptFullPath, script); if (!TryFindRScript(consoleLogger, out string rscriptPath)) { yield break; } var start = new ProcessStartInfo { UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true, CreateNoWindow = true, FileName = rscriptPath, WorkingDirectory = summary.ResultsDirectoryPath, Arguments = $"\"{scriptFullPath}\" \"{csvFullPath}\"" }; using (var process = new Process { StartInfo = start }) using (AsyncProcessOutputReader reader = new AsyncProcessOutputReader(process)) { // When large R scripts are generated then ran, ReadToEnd() // causes the stdout and stderr buffers to become full, // which causes R to hang. To avoid this, use // AsyncProcessOutputReader to cache the log contents // then write to disk rather than Process.Standard*.ReadToEnd(). process.Start(); reader.BeginRead(); process.WaitForExit(); reader.StopRead(); File.WriteAllLines(logFullPath, reader.GetOutputLines()); File.AppendAllLines(logFullPath, reader.GetErrorLines()); } yield return(Path.Combine(summary.ResultsDirectoryPath, $"*{ImageExtension}")); }
internal static (int exitCode, ImmutableArray <string> output) RunAndReadOutputLineByLine(string fileName, string arguments = "", string workingDirectory = "", Dictionary <string, string> environmentVariables = null, bool includeErrors = false, ILogger logger = null) { var processStartInfo = new ProcessStartInfo { FileName = fileName, WorkingDirectory = workingDirectory, Arguments = arguments, UseShellExecute = false, CreateNoWindow = true, RedirectStandardOutput = true, RedirectStandardError = true }; if (environmentVariables != null) { foreach (var environmentVariable in environmentVariables) { processStartInfo.Environment[environmentVariable.Key] = environmentVariable.Value; } } using (var process = new Process { StartInfo = processStartInfo }) using (var outputReader = new AsyncProcessOutputReader(process)) using (new ConsoleExitHandler(process, logger ?? NullLogger.Instance)) { process.Start(); outputReader.BeginRead(); process.WaitForExit(); outputReader.StopRead(); var output = includeErrors ? outputReader.GetOutputAndErrorLines() : outputReader.GetOutputLines(); return(process.ExitCode, output); } }