![Image 1](/KB/recipes/AdvCmdLineParserNET/command-line-app.png)
Introduction
While I was working on the docking framework DocktorUI library, I felt a part of the code, though useful in some cases, was really old and completely off the scope of the project and didn't fit quite right with the rest. So I decided to remove it, but again, because I considered it could be of use to some people, instead of throwing it away, it would have been better to make it available to those few people. The code was made of a set of C# classes used for a general application startup control. A few classes were aimed at IPC (inter-process communication) through the usage of Windows named pipes, plus another class which is instead dedicated to parsing Windows or Unix style command lines. I decided to only provide the latter, as Named Pipes are now handled by .NET 3.5, thus making my IPC code more or less obsolete.
Background
I know there are other options around offering similar functionality. I'm not pretending to assume this is any better or more complete, nor does it introduce anything new I guess. I haven't checked the others so I couldn't even tell. I already had this code, so I'm just making it public. Hopefully, it will be of use to somebody.
Using the code
The CommandLine
class allows an application to have intricate command line parsing built-in. Keep in mind that this code hasn't really been used in production, so it could have a few flaws. The class is pretty straightforward to use, plus it's heavily commented.
CommandLine cmdLine = new CommandLine(args);
String arg = cmdLine["name"];
I think the code is pretty self-explanatory. You can instantiate the class with a list of parameters or a string containing the entire command line. The parsing is done in-line using grammatic analysis, similar to how a generated lexer would do it. This makes it easier to add/change functionality, at least in my opinion. There's also a draft of an equivalent grammar in the comments. Although this is just a guideline model, it hasn't actually been used to generate the parsing code. Here is the mentioned grammar:
Here's the complete demo application code that can probably make it even more clear on the features offered by the class:
using System;
using System.Collections.Generic;
using System.Text;
using StartUp;
namespace CommandLineDemo
{
class Program
{
static void Main(string[] args)
{
CommandLine cmdLine = new CommandLine(args);
PrintCommandLine(cmdLine);
Console.WriteLine("Insert Command Line to parse or Return to exit.");
String cmd = Console.ReadLine();
while (!String.IsNullOrEmpty(cmd))
{
cmdLine.ParametersString = cmd;
PrintCommandLine(cmdLine);
cmd = Console.ReadLine();
}
}
static void PrintCommandLine(CommandLine cmdLine)
{
String cmd = cmdLine.ParametersString;
IDictionary<String, String> args = cmdLine.Parameters;
if (!String.IsNullOrEmpty(cmd))
{
if (cmdLine.Success)
{
Console.WriteLine("Command Line parsed successfully. Result:");
foreach (String key in args.Keys)
{
Console.WriteLine("\"{0}\" => \"{1}\"", key, args[key]);
}
}
else
{
Console.WriteLine("Error while parsing Command Line. " +
"Position marked with <---:");
int offset = cmdLine.ErrorOffset + 1;
Console.WriteLine("{0}<---{1}",
cmd.Substring(0, offset), cmd.Substring(offset));
}
}
}
}
}
Conclusions
I'd like to conclude by repeating the sort-of disclaimer above: I know there's been already other solutions offering the same functionality. Mine doesn't necessarily add anything new or better. I just wanted to share this old code that I had. That being said, I hope you find it somehow useful or interesting.