예제 #1
0
        public static async Task <string> GetOutputAsync(
            this IExecutable executable,
            ArgumentString arguments  = default,
            byte[] input              = null,
            Encoding outputEncoding   = null,
            CommandCache cache        = null,
            bool stripAnsiEscapeCodes = true)
        {
            if (outputEncoding == null)
            {
                outputEncoding = _defaultOutputEncoding.Value;
            }

            if (cache != null && cache.TryGet(arguments, out var output, out var error))
            {
                return(ComposeOutput());
            }

            using (var process = executable.Start(
                       arguments,
                       createWindow: false,
                       redirectInput: input != null,
                       redirectOutput: true,
                       outputEncoding))
            {
                if (input != null)
                {
                    await process.StandardInput.BaseStream.WriteAsync(input, 0, input.Length);

                    process.StandardInput.Close();
                }

                var outputBuffer = new MemoryStream();
                var errorBuffer  = new MemoryStream();
                var outputTask   = process.StandardOutput.BaseStream.CopyToAsync(outputBuffer);
                var errorTask    = process.StandardError.BaseStream.CopyToAsync(errorBuffer);
                var exitTask     = process.WaitForExitAsync();

                await Task.WhenAll(outputTask, errorTask, exitTask);

                output = outputBuffer.ToArray();
                error  = errorBuffer.ToArray();

                if (cache != null && await exitTask == 0)
                {
                    cache.Add(arguments, output, error);
                }

                return(ComposeOutput());
            }

            string ComposeOutput()
            {
                return(CleanString(
                           stripAnsiEscapeCodes,
                           EncodingHelper.DecodeString(output, error, ref outputEncoding)));
            }
        }
예제 #2
0
        public async Task <IReadOnlyCollection <string> > GetListAsync(bool isTopLevelSearchOnly)
        {
            IProcess process = executor.Start("ls-files -coz -- *.sln", redirectOutput: true);
            string   output  = await process.StandardOutput.ReadToEndAsync();

            var result = output.Split(new[] { '\0' }, System.StringSplitOptions.RemoveEmptyEntries)
                         .Where(x => !isTopLevelSearchOnly || !x.Contains('/'))
                         .Select(x => Path.Combine(rootPath, x))
                         .Where(File.Exists)
                         .ToArray();

            return(result);
        }
예제 #3
0
        public async Task <IReadOnlyCollection <string> > GetListAsync(bool isTopLevelSearchOnly, bool includeWorkspaces)
        {
            string   command = "ls-files -cz *.sln" + (includeWorkspaces ? " *.code-workspace" : "");
            IProcess process = executor.Start(command, redirectOutput: true, outputEncoding: Encoding.Default);
            string   output  = await process.StandardOutput.ReadToEndAsync();

            var result = output.Split(new[] { '\0' }, System.StringSplitOptions.RemoveEmptyEntries)
                         .Where(x => !isTopLevelSearchOnly || !x.Contains('/'))
                         .Select(x => Path.Combine(rootPath, x))
                         .Where(File.Exists)
                         .ToArray();

            return(result);
        }
예제 #4
0
        public IProcess RunDetached(
            ArgumentString arguments = default,
            bool createWindow        = false,
            bool redirectInput       = false,
            bool redirectOutput      = false,
            Encoding outputEncoding  = null)
        {
            if (outputEncoding is null && redirectOutput)
            {
                outputEncoding = _defaultEncoding();
            }

            return(_gitExecutable.Start(arguments, createWindow, redirectInput, redirectOutput, outputEncoding));
        }
예제 #5
0
        public static IEnumerable <string> GetOutputLines(
            this IExecutable executable,
            ArgumentString arguments  = default,
            byte[] input              = null,
            Encoding outputEncoding   = null,
            bool stripAnsiEscapeCodes = true)
        {
            // TODO make this method async, maybe via IAsyncEnumerable<...>?

            if (outputEncoding == null)
            {
                outputEncoding = _defaultOutputEncoding.Value;
            }

            using (var process = executable.Start(arguments, createWindow: false, redirectInput: input != null, redirectOutput: true, outputEncoding))
            {
                if (input != null)
                {
                    process.StandardInput.BaseStream.Write(input, 0, input.Length);
                    process.StandardInput.Close();
                }

                while (true)
                {
                    var line = process.StandardOutput.ReadLine();

                    if (line == null)
                    {
                        break;
                    }

                    yield return(CleanString(stripAnsiEscapeCodes, line));
                }

                while (true)
                {
                    var line = process.StandardError.ReadLine();

                    if (line == null)
                    {
                        break;
                    }

                    yield return(CleanString(stripAnsiEscapeCodes, line));
                }

                process.WaitForExit();
            }
        }
예제 #6
0
        /// <summary>
        /// Launches a process for the executable and returns <c>true</c> if its exit code is zero.
        /// </summary>
        /// <param name="executable">The executable from which to launch a process.</param>
        /// <param name="arguments">The arguments to pass to the executable.</param>
        /// <param name="input">Bytes to be written to the process's standard input stream, or <c>null</c> if no input is required.</param>
        /// <param name="createWindow">A flag indicating whether a console window should be created and bound to the process.</param>
        /// <returns>A task that yields <c>true</c> if the process's exit code was zero, otherwise <c>false</c>.</returns>
        public static async Task <bool> RunCommandAsync(
            this IExecutable executable,
            ArgumentString arguments = default,
            byte[]?input             = null,
            bool createWindow        = false)
        {
            using var process = executable.Start(arguments, createWindow: createWindow, redirectInput: input is not null);
            if (input is not null)
            {
                await process.StandardInput.BaseStream.WriteAsync(input, 0, input.Length);

                process.StandardInput.Close();
            }

            return(await process.WaitForExitAsync() == 0);
        }
        public void Setup()
        {
            _standardOutputStream = new MemoryStream();
            _standardErrorStream  = new MemoryStream();
            _outputStreamReader   = new StreamReader(_standardOutputStream);
            _errorStreamReader    = new StreamReader(_standardErrorStream);

            _process = Substitute.For <IProcess>();
            _process.StandardOutput.Returns(x => _outputStreamReader);
            _process.StandardError.Returns(x => _errorStreamReader);

            _executable = Substitute.For <IExecutable>();
            _executable.Start(Arg.Any <ArgumentString>(), Arg.Any <bool>(), Arg.Any <bool>(), Arg.Any <bool>(), Arg.Any <Encoding>()).Returns(x => _process);

            _provider = new AheadBehindDataProvider(() => _executable);
        }
        /// <summary>
        /// Launches a process for the executable and returns an object detailing exit code, standard output and standard error values.
        /// </summary>
        /// <param name="executable">The executable from which to launch a process.</param>
        /// <param name="arguments">The arguments to pass to the executable</param>
        /// <param name="writeInput">A callback that writes bytes to the process's standard input stream, or <c>null</c> if no input is required.</param>
        /// <param name="outputEncoding">The text encoding to use when decoding bytes read from the process's standard output and standard error streams, or <c>null</c> if the default encoding is to be used.</param>
        /// <param name="stripAnsiEscapeCodes">A flag indicating whether ANSI escape codes should be removed from output strings.</param>
        /// <returns>A task that yields an <see cref="ExecutionResult"/> object that gives access to exit code, standard output and standard error values.</returns>
        public static async Task <ExecutionResult> ExecuteAsync(
            this IExecutable executable,
            ArgumentString arguments,
            Action <StreamWriter> writeInput = null,
            Encoding outputEncoding          = null,
            bool stripAnsiEscapeCodes        = true)
        {
            if (outputEncoding == null)
            {
                outputEncoding = _defaultOutputEncoding.Value;
            }

            using (var process = executable.Start(arguments, createWindow: false, redirectInput: writeInput != null, redirectOutput: true, outputEncoding))
            {
                var outputBuffer = new MemoryStream();
                var errorBuffer  = new MemoryStream();
                var outputTask   = process.StandardOutput.BaseStream.CopyToAsync(outputBuffer);
                var errorTask    = process.StandardError.BaseStream.CopyToAsync(errorBuffer);

                if (writeInput != null)
                {
                    // TODO do we want to make this async?
                    writeInput(process.StandardInput);
                    process.StandardInput.Close();
                }

                var exitTask = process.WaitForExitAsync();

                await Task.WhenAll(outputTask, errorTask, exitTask);

                var output = outputEncoding.GetString(outputBuffer.GetBuffer(), 0, (int)outputBuffer.Length);
                var error  = outputEncoding.GetString(errorBuffer.GetBuffer(), 0, (int)errorBuffer.Length);

                var exitCode = await process.WaitForExitAsync();

                return(new ExecutionResult(
                           CleanString(stripAnsiEscapeCodes, output),
                           CleanString(stripAnsiEscapeCodes, error),
                           exitCode));
            }
        }
예제 #9
0
        public void StartSync()
        {
            executable.Stopped           += new EventHandler(executable_Stopped);
            executable.Paused            += new EventHandler(executable_Paused);
            executable.ExceptionOccurred += new EventHandler <EventArgs <Exception> >(executable_ExceptionOccurred);

            using (CancellationTokenRegistration registration = cancellationToken.Register(new Action(cancellationToken_Canceled))) {
                executable.Start();
                waitHandle.WaitOne(-1, false);
                waitHandle.Dispose();
            }

            executable.Stopped -= new EventHandler(executable_Stopped);
            executable.Paused  -= new EventHandler(executable_Paused);
            if (executable.ExecutionState == ExecutionState.Started)
            {
                executable.Pause();
            }
            cancellationToken.ThrowIfCancellationRequested();
            if (occuredException != null)
            {
                throw occuredException;
            }
        }