/// <inheritdoc /> protected override async Task <Result <Unit, IError> > Run( IStateMonad stateMonad, CancellationToken cancellationToken) { var r = await Value.Run(stateMonad, cancellationToken); if (r.IsFailure) { return(r.ConvertFailure <Unit>()); } var stringToPrint = await SerializationMethods.GetStringAsync(r.Value); stateMonad.Log(LogLevel.Information, stringToPrint, this); return(Unit.Default); }
/// <inheritdoc /> public async Task <Result <Unit, IErrorBuilder> > RunExternalProcess( string processPath, IErrorHandler errorHandler, IEnumerable <string> arguments, IReadOnlyDictionary <string, string> environmentVariables, Encoding encoding, IStateMonad stateMonad, IStep?callingStep, CancellationToken cancellationToken) { var absolutePath = GetAbsolutePath(processPath); if (absolutePath.IsFailure) { return(absolutePath.ConvertFailure <Unit>()); } var argumentString = string.Join(' ', arguments.Select(EncodeParameterArgument)); LogSituation.ExternalProcessStarted.Log( stateMonad, callingStep, absolutePath.Value, argumentString ); using var pProcess = new Process { StartInfo = { FileName = absolutePath.Value, Arguments = argumentString, UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true, WindowStyle = ProcessWindowStyle.Hidden, //don't display a window CreateNoWindow = true, StandardErrorEncoding = encoding, StandardOutputEncoding = encoding } }; foreach (var(key, value) in environmentVariables) { pProcess.StartInfo.EnvironmentVariables.Add( key, value ); } foreach (var(key, value) in pProcess.StartInfo.Environment) { LogSituation.EnvironmentVariable.Log(stateMonad, callingStep, key, value); } var errors = new List <IErrorBuilder>(); try { pProcess.Start(); var channelReader = StreamChannelHelper.ToChannelReader( (pProcess.StandardOutput, StreamSource.Output), (pProcess.StandardError, StreamSource.Error) ); await foreach (var(line, streamSource) in channelReader.ReadAllAsync(cancellationToken) ) { if (streamSource == StreamSource.Error) { var errorText = string.IsNullOrWhiteSpace(line) ? "Unknown Error" : line; if (errorHandler.ShouldIgnoreError(errorText)) { stateMonad.Log(LogLevel.Warning, line, callingStep); } else { errors.Add(new ErrorBuilder(ErrorCode.ExternalProcessError, errorText)); } } else { stateMonad.Log(LogLevel.Information, line, callingStep); } } // ReSharper disable once MethodHasAsyncOverloadWithCancellation - run on a separate thread pProcess.WaitForExit(); } #pragma warning disable CA1031 // Do not catch general exception types catch (Exception e) { errors.Add(new ErrorBuilder(e, ErrorCode.ExternalProcessError)); } #pragma warning restore CA1031 // Do not catch general exception types if (errors.Any()) { var e = ErrorBuilderList.Combine(errors); return(Result.Failure <Unit, IErrorBuilder>(e)); } return(Unit.Default); }