using System; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Threading; using MalwareMultiScan.Backends.Services.Interfaces; using Microsoft.Extensions.Logging; namespace MalwareMultiScan.Backends.Services.Implementations { /// /// /// [ExcludeFromCodeCoverage] public class ProcessRunner : IProcessRunner { private readonly ILogger _logger; /// /// Initialize process runner. /// /// Logger. public ProcessRunner(ILogger logger) { _logger = logger; } /// /// /// /// /// /// /// /// /// /// public int RunTillCompletion(string path, string arguments, CancellationToken cancellationToken, out string standardOutput, out string standardError) { var process = new Process { StartInfo = new ProcessStartInfo(path, arguments) { RedirectStandardError = true, RedirectStandardOutput = true, WorkingDirectory = Path.GetDirectoryName(path) ?? Directory.GetCurrentDirectory() } }; _logger.LogInformation( $"Starting process {process.StartInfo.FileName} " + $"with arguments {process.StartInfo.Arguments} " + $"in working directory {process.StartInfo.WorkingDirectory}"); process.Start(); cancellationToken.Register(() => { if (process.HasExited) return; process.Kill(true); throw new TimeoutException("Scanning failed to complete within the timeout"); }); process.WaitForExit(); _logger.LogInformation($"Process has exited with code {process.ExitCode}"); standardOutput = process.StandardOutput.ReadToEnd(); standardError = process.StandardError.ReadToEnd(); _logger.LogDebug($"Process standard output: {standardOutput}"); _logger.LogDebug($"Process standard error: {standardError}"); return process.ExitCode; } } }