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))); } }
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); }
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); }
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)); }
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(); } }
/// <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)); } }
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; } }