AutoCmd 1.0.0

dotnet add package AutoCmd --version 1.0.0
NuGet\Install-Package AutoCmd -Version 1.0.0
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="AutoCmd" Version="1.0.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add AutoCmd --version 1.0.0
#r "nuget: AutoCmd, 1.0.0"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install AutoCmd as a Cake Addin
#addin nuget:?package=AutoCmd&version=1.0.0

// Install AutoCmd as a Cake Tool
#tool nuget:?package=AutoCmd&version=1.0.0

AutoCmd

AutoCmd is a simple library to monitor the standard output of a console application and write to standard input when a key word is detected.

The use case this was made for was the automation of entry of credentials into a console application.

Usage

Create an AutoProcess instance, and set the FileName of the command line executable. You can also set the Arguments and WorkingDirectory as required. These are passed directly to the Process object later.

var auto = new AutoProcess()
{
    FileName = "getcred.cmd"
};

Create one or more AutoResponders. Set the Match property to the exact string to match when a response will occur. Set the Respond property to a delegate or anonymous function that accepts a Process instance. Within the response method, you can call process.StandardInput.WriteLine to send text

var usernameResponder = new AutoResponder()
{
    Match = "Username:",
    Respond = (proc) =>
    {
        proc.StandardInput.WriteLine("ADMIN");
        // Because we're not typing to the screen, we need to insert a newline as if we pressed enter
        // This is not actually needed and doesn't affect the response, it only makes it look "normal" on screen
        Console.WriteLine();
    }
};

var passwordResponder = new AutoResponder()
{
    Match = "Password:",
    Respond = (proc) =>
    {
        proc.StandardInput.WriteLine("12345!");
        Console.WriteLine();
    }
};

var pressAnyKeyResponder = new AutoResponder()
{
    Match = "Press any key to continue . . .",
    Respond = (proc) =>
    {
        proc.StandardInput.WriteLine();
        Console.WriteLine();
    }
};

Add them to the AutoProcess with AddResponder, and finally call Start() on the AutoProcess.

auto.AddResponder(usernameResponder);
auto.AddResponder(passwordResponder);
auto.AddResponder(pressAnyKeyResponder);
auto.Start();            

This will launch the process and begin tracking the output.

How it works

A Process is created with StandardInput and StandardOuput redirected and the process is started. A thread is created to read the StandardOutput stream character by character. Note that this may cause some latency in the output.

Each read character is fed into the responders with the Read(char character) method, which starts matching characters when the first character in the Match property is matched. This is just a simple match that advances the character pointer each time a match is made, and resets it on failure.

If the match completes, the Respond method is called with the process instance as the argument.

Notes

The library calls WaitForExit() on the process to wait until it completes. Due to the latency in output, it's possible that the process may complete while the thread is still busy reading characters and outputting to screen. To prevent the process being closed prematurely, an AutoResetEvent is used to synchronize the completion of a StandardInput.Read() to empty the buffer with the completion of WaitForExit(). This hasn't really been tested extensively.

This library cannot read a dynamically updated console output, such as progress information updated on the same line, or the TIMEOUT command.

This was put together for a specific, simple use case and may not exactly fit your needs.

Extending AutoCmd

You can create your own Responder by implementing IResponder.

Adding stuff like regex might be a bit more complicated as regex doesn't work on a character level. I've thought about it and you might need to wait for the output to stop by checking how long before Read was called before doing anything. This is because matching something that "starts with" a pattern would require the output to "complete" before matching.

Other libraries

I looked at some other libraries but they did not seem to be able to do exactly what was needed.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 is compatible.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETFramework 4.6.2

    • No dependencies.
  • .NETStandard 2.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.0.0 328 9/19/2021