Popularity
1.5
Declining
Activity
0.0
Stable
28
3
3

Description

A library to run sub-processes on .net By Gene Thomas

Gt.SubProcess is on nuget - Install-Package Gt.SubProcess.

The Process class has a unusable string StartInfo.Arguments, the rules around quoting "s are complex so one can not just concatenate arguments to be passed in. SubProcess takes a list of strings and handles the quoting internally. By default the standard output and standard error are captured into strings, accessible as .OutputString and ErrorString after the sub-process has started.

Programming language: C#
License: MIT License
Tags: Assembly Manipulation     process     C     Sub-process    

Gt.SubProcess alternatives and similar packages

Based on the "Assembly Manipulation" category.
Alternatively, view Gt.SubProcess alternatives based on common mentions on social networks and blogs.

Do you think we are missing an alternative of Gt.SubProcess or a related project?

Add another 'Assembly Manipulation' Package

README

Gt.SubProcess

A library to run sub-processes on .net By Gene Thomas

Gt.SubProcess is on nuget - Install-Package Gt.SubProcess.

The Process class has a unusable string StartInfo.Arguments, the rules around quoting "s are complex so one can not just concatenate arguments to be passed in. SubProcess takes a list of strings and handles the quoting internally. By default the standard output and standard error are captured into strings, accessible as as .OutputString and ErrorString after the sub-process has started.

    using System;
    using System.IO;
    using Gt.SubProcess;

    namespace ReadmeExample
    {
        class Program
        {
            static int Main(string[] args) { 
                try {
                    SubProcess.Call("ls", "-l");

                    SubProcess.CheckCall("psql", "my-database", "fred");
                        // throws if exits with non 0 exit code

                    SubProcess p = new SubProcess("ssh", "[email protected]")
                    {
                        Out = new FileStream("ssh-output.txt", FileMode.OpenOrCreate),
                        Error = SubProcess.Capture,
                        In = SubProcess.Pipe                    
                    };
                    p.Wait();

                    Console.WriteLine(p.ErrorString);

                    return 0; 
                } catch (Exception e) { 
                    Console.Error.WriteLine("Fatal Error: " + e.Message); 
                    return 1; 
                }
            } 
        }
    }

Static methods

SubProcess has a number of static methods which do not require one to create a SubProcess object.

SubProcess.Call("ls", "-l", "-r", "-t") and SubProcess.Call(IEnumerable<string>) run the program and return it's int return code. Output is not captured.

SubProcess.CheckCall("ls", "-l", "-r", "-t") and SubProcess.CheckCall(IEnumerable<string>) run the program and throw a Failed exception if the program exits with a non zero exit code.

SubProcess.CheckOutput("ls", "-l", "-r", "-t").With(expectedString) and CheckOutput(IEnumerable<string>).With(expectedString) run the program, throw Failed exception if it exits with a non-zero exide code and throw an UnexpectedOutput exception if the program's standed output is not as expected, as specified in the .With(string) part.

If you need more control over the sub-process create and intance of SubProcess and initialise as required.

SubProcess objects

SubProcess objects are created with a list of strings inline, e.g. var p = new SubProcess("ls", "-l") or with an IEnumerable<string>, e.g. a List<string>. There a number of methods and properties that can be used to launch and run the program as required.

Startup methods and properties

In

Set how the subprocess's input is handled:

  • In = new FileStream("input.txt", FileMode.Open); a stream
  • In = SubProcess.Through Read from the terminal
  • In = SubProcess.Swallow no input
  • In = SubProcess.Pipe the default allows Write()/WriteLine() of string or byte[]s

Out

Set how the subprocess's output is handled:

  • Out = new FileStream("output.txt", FileMode.OpenOrCreate); a stream
  • Out = SubProcess.Through let the output be printed to the terminal
  • Out = SubProcess.Capture the default to string string output = subprocess.OutputString
  • Out = SubProcess.Swallow throw away
  • Out = SubProcess.Pipe read incremenally Stream stream = subprocess.OutputStream TextReader reader = subprocess.OutputReader

Error

Set how the subprocess's error output is handled:

  • Error = new FileStream("error.txt", FileMode.OpenOrCreate); a stream
  • Error = SubProcess.Through let the error output be printed to the terminal
  • Error = SubProcess.Capture the default to string string errorMessage = subprocess.ErrorString
  • Error = SubProcess.Swallow throw away
  • Error = SubProcess.ToOut redirect Error to Out
  • Error = SubProcess.Pipe read incremenally Stream stream = subprocess.ErrorStream TextReader reader = subprocess.ErrorReader

string Directory

Set the directory to start the process in.

Dictionary<string, string> Environment

Set environment variabled for the process. e.g.

    new SubProcess("my-app") {
        Environment = {
            ["NAME"] = "VALUE"
        }
    };

double Timeout

Timeout after given number of seconds. Throw TimeoutException if the process does not exit in the given time.

Add(string arg)

Add an item to the process arguments list. e.g. p.Add("--verbose");

Add(string options, string value)

Add an item to the process arguments list. e.g. p.Add("--name", "fred");

Methods and properties of a running SubProcess

bool HasStarted

Returns true if the sub-process has started.

string ToString()

Returns the argument list formatted using quotes as required.

void Start()

Set the sub-process running.

int Wait()

Wait for the process to exit, Start()ing if required. Returns the processes' exit code.

void Check()

Wait for the process to exit, Start()ing if required. Throw a Failed if the sub-process exits with a non-zero exit code.

void Kill()

Terminate the sub-process. This happens asynchronously, we do not wait for the sub-process to exit.

int ExitCode

The number that the sub-process exited with. Traditionally 0 means a good exit, and non-zero means a problem occured.

bool HasExited

Returns true of the sub-process has run and exited.

bool IsAlive

Returns true of the sub-process is still runnning.

string ExecutableName

Returns the name of the sub-process.

void Write(string input)

Write the given string to the sub-processes' standard input. The SubProcess must have been started with In = SubProcess.Pipe, the default.

void Write(byte[] buffer, int offset, int count)

Write the given bytes, from offset and of length count to the processes' standard input. The SubProcess must have been started with In = SubProcess.Pipe,

void WriteLine(string input)

Write the given string to the sub-processes' standard input and append a newline. The SubProcess must have been started with In = SubProcess.Pipe, the default.

string OutputString

Return a string containing the sub-processes' captured standard output. The encoding defaults to UTF-8 but can be set using the startup OutputEncoding propery. The Out property must be set to SubProcess.Capture or SubProcess.Pipe at startup.

string ErrorString

Return a string containing the sub-processes' captured standard error. The encoding defaults to UTF-8 but can be set using the startup OutputEncoding propery. The Error property must be set to SubProcess.Capture or SubProcess.Pipe at startup.

TextReader OutputReader

Return a TextReader to read the sub-processes' standard output. The encoding defaults to UTF-8 but can be set using the startup OutputEncoding propery. The Out property must be set to Pipe for this to wok.

TextReader ErrorReader

Return a TextReader to read the sub-processes' standard error. The encoding defaults to UTF-8 but can be set using the startup ErrorEncoding propery. The Error property must be set to Capture or Pipe at startup. orPipe` at startup.

Stream OutputStream

Return a Stream to read the sub-processes' standard error. Outmust be set to SubProcess.Capture` for this to work.

Stream ErrorStream

Return a Stream to read the sub-processes' standard error. Errormust be set to SubProcess.Pipe` for this to work.

bool HasTimeout

Return true if the sub-process took too long.

async Task Check()

Asynchronous version of Check(). Wait for the process to exit, Start()ing if required. Throw a Failed if the sub-process exits with a non-zero exit code.

IDisposable interface

SubProcess inherits from IDisposable so can be used with a using block to ensure that the sub-process is terminated. e.g.

   using (SubProcess p = new SubProcess("find", ".", "-name", "*.exe"))
   {
        // do something
   }

Kill() is used if we leave the using block without p exiting.