public static void ResultShouldBe([NotNull] this CommandLineResult actualResult, [NotNull] CommandLineResult expectedResult, [CanBeNull] bool?producesTeamCityServiceMessages = null)
        {
            if (actualResult == null)
            {
                throw new ArgumentNullException(nameof(actualResult));
            }
            if (expectedResult == null)
            {
                throw new ArgumentNullException(nameof(expectedResult));
            }
            actualResult.ExitCode.ShouldBe(expectedResult.ExitCode);
            CheckOutput(actualResult.StdOut, expectedResult.StdOut);
            CheckOutput(actualResult.StdError, expectedResult.StdError);
            if (producesTeamCityServiceMessages.HasValue)
            {
                (ServiceMessages.GetNumberServiceMessage(actualResult.StdOut) > 0).ShouldBe(producesTeamCityServiceMessages.Value);
            }

            ServiceMessages.ResultShouldContainCorrectStructureAndSequence(actualResult.StdOut);
            ServiceMessages.ResultShouldContainCorrectStructureAndSequence(actualResult.StdError);
        }
        public bool TryExecute(out CommandLineResult result)
        {
            var process = new Process
            {
                StartInfo = new ProcessStartInfo
                {
                    WorkingDirectory       = WorkingDirectory,
                    FileName               = ExecutableFile,
                    Arguments              = string.Join(" ", Args.Select(NormalizeArg).ToArray()),
                    RedirectStandardError  = true,
                    RedirectStandardOutput = true,
                    CreateNoWindow         = true,
                    UseShellExecute        = false
                }
            };

            foreach (var envVar in _environmentVariables)
            {
#if NET45
                if (envVar.Value == null)
                {
                    process.StartInfo.EnvironmentVariables.Remove(envVar.Key);
                }
                else
                {
                    process.StartInfo.EnvironmentVariables[envVar.Key] = envVar.Value;
                }
#else
                if (envVar.Value == null)
                {
                    process.StartInfo.Environment.Remove(envVar.Key);
                }
                else
                {
                    process.StartInfo.Environment[envVar.Key] = envVar.Value;
                }
#endif
            }

            IList <string> stdOut   = new List <string>();
            IList <string> stdError = new List <string>();
            process.OutputDataReceived += (sender, args) =>
            {
                if (args.Data != null)
                {
                    stdOut.Add(args.Data);
                    //Console.Write(".");
                }
            };

            process.ErrorDataReceived += (sender, args) =>
            {
                if (args.Data != null)
                {
                    stdError.Add(args.Data);
                    Console.Error.WriteLine(args.Data);
                }
            };

            // ReSharper disable once LocalizableElement
            Console.WriteLine($"Run: {process.StartInfo.FileName} {process.StartInfo.Arguments}");
            var stopwatch = new Stopwatch();
            if (!process.Start())
            {
                result = default(CommandLineResult);
                return(false);
            }

            stopwatch.Start();
            Console.WriteLine($@"Process Id: {process.Id}");

            process.BeginOutputReadLine();
            process.BeginErrorReadLine();

            process.WaitForExit(20000).ShouldBe(true, "Timeout");
            stopwatch.Stop();
            Console.WriteLine($@"Elapsed Milliseconds: {stopwatch.ElapsedMilliseconds}");

            result = new CommandLineResult(this, process.ExitCode, stdOut, stdError);
            return(true);
        }