public async Task Run()

in src/AWS.Deploy.CLI/Utilities/CommandLineWrapper.cs [39:142]


        public async Task Run(
            string command,
            string workingDirectory = "",
            bool streamOutputToInteractiveService = true,
            Action<TryRunResult>? onComplete = null,
            bool redirectIO = true,
            IDictionary<string, string>? environmentVariables = null,
            CancellationToken cancelToken = default,
            bool needAwsCredentials = false)
        {
            StringBuilder strOutput = new StringBuilder();
            StringBuilder strError = new StringBuilder();

            var processStartInfo = new ProcessStartInfo
            {
                FileName = GetSystemShell(),

                Arguments =
                    RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
                        ? $"/c {command}"
                        : $"-c \"{command}\"",

                RedirectStandardInput = redirectIO,
                RedirectStandardOutput = redirectIO,
                RedirectStandardError = redirectIO,
                UseShellExecute = false,
                CreateNoWindow = redirectIO,
                WorkingDirectory = workingDirectory
            };

            // If the command output is not being redirected check to see if
            // the output should go to a separate console window. This is important when run from
            // an IDE which won't have a console window by default.
            if (!streamOutputToInteractiveService && !redirectIO)
            {
                processStartInfo.UseShellExecute = _useSeparateWindow;
            }

            UpdateEnvironmentVariables(processStartInfo, environmentVariables);

            if (needAwsCredentials)
                _processStartInfoAction?.Invoke(processStartInfo);

            var process = Process.Start(processStartInfo);
            if (null == process)
                throw new Exception("Process.Start failed to return a non-null process");

            if (redirectIO)
            {
                process.OutputDataReceived += (sender, e) =>
                {
                    if(streamOutputToInteractiveService)
                    {
                        _interactiveService.LogMessageLine(e.Data);
                    }

                    strOutput.AppendLine(e.Data);
                };

                process.ErrorDataReceived += (sender, e) =>
                {
                    if(streamOutputToInteractiveService)
                    {
                        _interactiveService.LogMessageLine(e.Data);
                    }

                    strError.AppendLine(e.Data);
                };
                process.BeginOutputReadLine();
                process.BeginErrorReadLine();
            }

            // poll for process to prevent blocking the main thread
            // as opposed to using process.WaitForExit()
            // in .net5 we can use process.WaitForExitAsync()
            while (true)
            {
                if (process.HasExited)
                {
                    // In some cases, process might have exited but OutputDataReceived or ErrorDataReceived could still be writing
                    // asynchronously, adding a delay should cover most of the cases.
                    await Task.Delay(TimeSpan.FromSeconds(1), cancelToken);
                    break;
                }

                await Task.Delay(TimeSpan.FromMilliseconds(50), cancelToken);
            }

            if (onComplete != null)
            {
                var result = new TryRunResult
                {
                    ExitCode = process.ExitCode
                };

                if (redirectIO)
                {
                    result.StandardError = strError.ToString();
                    result.StandardOut = strOutput.ToString();
                }

                onComplete(result);
            }
        }