How to interact with applications via command line in C#
As with most programming languages, C# has the facilities to start other applications via command line. Such facilities may not be of much interest to the ardent C# programmer, who will want to fulfill every business logic with purely C# codes in his/her program. However, there are times when it is necessary to interface with applications that other people had already built for us.
Why do we have to leverage on applications via command line in C#?
We may have to do so because of the following reasons:
- An application had cost too much in the past and business wants to avoid spending additional time and resources to replicate its functionality in C#.
- The third party vendor gave an C# api which had broken functionailities and the command line tool that they provide is the only option that can be leveraged on.
- There are certain functionalities that is not available (or easily available) in C# but is a given in windows through its huge application repository.
In this post, I document three examples on how we can interface with other applications via command line in C#.
Start a web browser to display a webpage from C#
Let's start off with a minimal example. Let's assume that I wish to show my website from my C# program.
That would be a similar to typing iexplore http://www.techcoil.com
in the command prompt to start internet explorer to show the home page of my website.
What happens when we do that?
That is actually an example of command line execution. We are actually requesting the operating system to start a process to run iexplore
(the executable for Internet Explorer), giving it http://www.techcoil.com
as a command line argument.
The following code segment is how we could do that in C#:
using System; using System.Diagnostics; using System.Text; public class LaunchInternetExplorer { public static void Main(string[] args) { Process ieProcess = new Process(); // Set the application that our Process is // going to start. ieProcess.StartInfo.FileName = "iexplore"; // Pass in the url that iexplore will visit upon // starting as a command line argument. ieProcess.StartInfo.Arguments = "http://www.techcoil.com"; // Start the command line execution ieProcess.Start(); } // public static void Main(string[] args) } // end public class LaunchInternetExplorer
This code segment began with creating an instance of the System.Diagnostic.Process
class.
The name of the application (iexplore) to start on command line is then set via the ieProcess.StartInfo.FileName
property. After that, the url to techcoil is provided as a command line argument via the ieProcess.StartInfo.Arguments
property.
When the relevant start up information is provided via the ieProcess.StartInfo
property, we start the process to launch internet explorer by calling ieProcess.Start()
.
So what is ieProcess.StartInfo
?
When we get our Process
instance, we also get an instance of the System.Diagnostics.ProcessStartInfo
, which contains startup information for the process when it starts running. This ProcessStartInfo
instance is accessible via the StartInfo
property of our Process instance.
Reading from standard output of command line application in C#
Unless our C# program is able to serve HTTP requests and we point internet explorer to its url, we are not interacting with the internet explorer process anymore in our previous code example.
However, there are times when we want to read the standard output of an application that we started from command line.
The following code segment demonstrates how we can read from the standard output of the ipconfig command:
using System; using System.Diagnostics; using System.IO; using System.Text; public class ReadFromStandardOutput { public static void Main(string[] args) { Process ipconfigProcess = new Process(); // Indicate that we want to execute ipconfig ipconfigProcess.StartInfo.FileName = "ipconfig"; ipconfigProcess.StartInfo.Arguments = "/all"; // Indicate that we want to read the command line output ipconfigProcess.StartInfo.RedirectStandardOutput = true; ipconfigProcess.StartInfo.UseShellExecute = false; // Start the process to execute ipconfig ipconfigProcess.Start(); // Get a StreamReader to read from the standard output of // the ipconfig process StreamReader reader = ipconfigProcess.StandardOutput; // Perform reading and writing of standard output to Console String line; while((line = reader.ReadLine()) != null) { Console.WriteLine(line); } // end while } // end public static void Main(string[] args) } // end public class ReadFromStandardOutput
In this case, we are getting our C# program to execute ipconfig /all
, which will display current TCP/IP network configurations for all adapters in our windows machine.
As with the internet explorer example, the above program first creates an instance of Process
and then supplies it with the application name to run and a command line argument string.
In addition to that, two other properties are being set - StartInfo.RedirectStandardOutput
and StartInfo.UseShellExecute
.
We set RedirectStandardOutput
to true because we want to be able to read from standard output; set UseShellExecute
to false because we cannot use the operating system shell to execute the command line application if we want to get its standard output.
When start information about the process had been provided to the Process
instance, we start the process to execute ipconfig /all
via command line.
Finally, we get a System.IO.StreamReader
instance from the StandardOutput property and use it to read the standard output, just like how we would read text from file.
Writing to standard input of command line application in C#
Sometimes, our C# program will need to interact with command line applications that collect input from the user through a command line interface. To interact with such application, we need to write to the standard input of the command line application.
Let's assume we have the following command line application, Greeter.exe
, that greets the user after asking for his/her name:
public class Greeter { public static void Main(string[] args) { Console.WriteLine("What's your name? "); String name = Console.ReadLine(); Console.WriteLine("Hello " + name + ". Nice to meet you!"); } // end public static void Main(string[] args) } // end public class Greeter
And right now, we want to interface with it from another C# program. The following code demonstrates how we can do so by writing to the standard input and reading from the standard output of Greeter.exe
.
public class WriteToStandardInputOfGreeter { public static void Main(string[] args) { Process greeterProcess = new Process(); greeterProcess.StartInfo.FileName = "Greeter.exe"; // Indicate that we want to read from standard output // of process greeterProcess.StartInfo.RedirectStandardInput = true; // Indicate that we want to write to standard input of // process greeterProcess.StartInfo.RedirectStandardOutput = true; greeterProcess.StartInfo.UseShellExecute = false; greeterProcess.Start(); // Get a StreamWriter to write to the standard input of // Greeter.exe StreamWriter writer = greeterProcess.StandardInput; // Get a StreamReader to read from standard output of // Greeter.exe StreamReader reader = greeterProcess.StandardOutput; // Get the question from greeter Console.WriteLine("Question from greeter: "); Console.WriteLine(reader.ReadLine()); // Answer Greeter with Robot writer.WriteLine("Robot"); Console.WriteLine("Response from greeter: "); Console.WriteLine(reader.ReadLine()); } // end public static void Main(string[] args) } // end public class WriteToStandardInputOfGreeter
Similar to the first two examples, the program begins with creating an instance of the Process
class.
Four pieces of start information are then supplied to the Process
instance:
- Name of the command line application to run, Greeter.exe, via the
StartInfo.FileName
property. - Indication for standard input redirection, via the
StartInfo.RedirectInputOutput
property. - Indication for standard output redirection, via the
StartInfo.RedirectStandardOutput
property. - Indication for not using the operating system shell, via the
StartInfo.UseShellExecute
property, so that our C# program can read from the standard output and write to the standard input ofGreeter.exe
.
The process is then started with a call to the greeterProcess.Start
.
After the process had started, we first get an instance of StreamReader
via the greeterProcess.StandardOutput
property and an instance of System.IO.StreamWriter
via the greeterProcess.StandardInput
property.
We then use the StreamReader instance to read the prompt for name input from Greeter.exe, write Robot to its Standard Input and read its response, which is the string "Hello Robot. Nice to meet you!".