Introduction
Even with modern UI, we often need a way to start our programs with specific parameters. Command line arguments are helpful to provide those parameters without exposing them to everybody. When developing with .NET and C# you can get the command line arguments from your Main(string[] Args)
function. Args
is in fact an array containing all the strings separated by spaces entered in the command line. What the following class does is to transform this array of strings into a ready to use collection of key/value pairs. You can then easily find and get from this collection a specific value for one of your parameters (key).
The Arguments class
This class parses your command line arguments, find all parameters starting with -, -- or / and all the values linked. I assumed that a value could be separated from a parameter with a space, a : or a =. The parser also look for enclosing characters like ' or " and remove them. Of course if you have a value like 'Mike's house'
, only the first and last ' will be removed. To achieve its goal, the class relies heavily on the regular expressions capabilities of .NET. The first regular expression (^-{1,2}|^/|=|:
) splits one argument into several parts:
This regular expression handles cases where only a parameter is present, only a value is present or if both are present. The program performs accordingly to the number of parts found. The second regular expression (^['"]?(.*?)['"]?$
) is used to detect and remove all starting and trailing ' or " characters from a value. When all your arguments are parsed, retrieving a value from a parameter is as easy as writing MyValue=params["MyParam"]
. If the parameter doesn't exist or was not in the command line then you will get a null
reference you can test against.
using System;
using System.Collections.Specialized;
using System.Text.RegularExpressions;
namespace CommandLine.Utility
{
public class Arguments{
private StringDictionary Parameters;
public Arguments(string[] Args)
{
Parameters = new StringDictionary();
Regex Spliter = new Regex(@"^-{1,2}|^/|=|:",
RegexOptions.IgnoreCase|RegexOptions.Compiled);
Regex Remover = new Regex(@"^['""]?(.*?)['""]?$",
RegexOptions.IgnoreCase|RegexOptions.Compiled);
string Parameter = null;
string[] Parts;
foreach(string Txt in Args)
{
Parts = Spliter.Split(Txt,3);
switch(Parts.Length){
case 1:
if(Parameter != null)
{
if(!Parameters.ContainsKey(Parameter))
{
Parts[0] =
Remover.Replace(Parts[0], "$1");
Parameters.Add(Parameter, Parts[0]);
}
Parameter=null;
}
break;
case 2:
if(Parameter!=null)
{
if(!Parameters.ContainsKey(Parameter))
Parameters.Add(Parameter, "true");
}
Parameter=Parts[1];
break;
case 3:
if(Parameter != null)
{
if(!Parameters.ContainsKey(Parameter))
Parameters.Add(Parameter, "true");
}
Parameter = Parts[1];
if(!Parameters.ContainsKey(Parameter))
{
Parts[2] = Remover.Replace(Parts[2], "$1");
Parameters.Add(Parameter, Parts[2]);
}
Parameter=null;
break;
}
}
if(Parameter != null)
{
if(!Parameters.ContainsKey(Parameter))
Parameters.Add(Parameter, "true");
}
}
public string this [string Param]
{
get
{
return(Parameters[Param]);
}
}
}
}
The test class
Here is an example of how to use the Arguments
class. As usual, the code is available in the zip file.
using System;
using CommandLine.Utility;
namespace CommandLine
{
class Test
{
[STAThread]
static void Main(string[] Args)
{
Arguments CommandLine=new Arguments(Args);
if(CommandLine["param1"] != null)
Console.WriteLine("Param1 value: " +
CommandLine["param1"]);
else
Console.WriteLine("Param1 not defined !");
if(CommandLine["height"] != null)
Console.WriteLine("Height value: " +
CommandLine["height"]);
else
Console.WriteLine("Height not defined !");
if(CommandLine["width"] != null)
Console.WriteLine("Width value: " +
CommandLine["width"]);
else
Console.WriteLine("Width not defined !");
if(CommandLine["size"] != null)
Console.WriteLine("Size value: " +
CommandLine["size"]);
else
Console.WriteLine("Size not defined !");
if(CommandLine["debug"] != null)
Console.WriteLine("Debug value: " +
CommandLine["debug"]);
else
Console.WriteLine("Debug not defined !");
Console.Out.WriteLine("Arguments parsed. Press a key");
Console.Read();
}
}
}
Execution sample
I provided the following command line as the Arguments setting in the properties dialog of the Visual Studio .NET solution included in the ZIP file: -size=100 /height:'400' -param1 "Nice stuff !" --debug
that command line produced the following output
Param1 value: Nice stuff !
Height value: 400
Width not defined !
Size value: 100
Debug value: true
Arguments parsed. Press a key...
Conclusion
In this article with saw how to parse, store and retrieve the arguments line of a .NET application. This class is versatile enough to handle a lot of different kind of arguments. Compatible with most of the forms we are used to (-param
, --param
or Windows /param
). Thanks to the regular expressions for this. Using regular expressions allowed us to keep the Arguments
class very small and the usage is very simple. Regular expressions are very powerful and can be used for most of your parsing needs (as far as speed is not the main concern).
Special thanks to: Benjamin, Guillaume and Sebastien for their support :o)
Happy Coding!!!
History
- October 28, 2002 - v1.0 Initial release
- November 6, 2002 - v1.1 Bug fix. Should be bug free now. Thanks to n2s for help.