There are a multitude of Argument Parsers available online. So why am I writing my own? Well to be frank… I did a search and couldn’t find anything that would be either “easy” to implement. I know that this is not much, but hope other programmers might find this useful if they are as lazy as I am and looking for a quick solution :-)
I was actually looking for a parser which would return something like a Hashtable which i can loop through and load the values into properties of some sort. So here is a stab at my own version of an argument parser which returns a hashtable. To be honest, I picked up a bit of the code from somewhere else, but I had to do a significant amount of changes to tweak it to my need.
So here are my requirements: -
- I need the arguments in a key value pair so i can use them at my leisure.
- I wanted to have arguments defined in a key=value format so i know which value matches with what.
- The parser should also ensure that no invalid entries are made.
And here are the directions for use. ..
Step 1 – Create a windows console application
Create a new Windows Console application in Visual Studio and call it “MyTestProject” (that’s what the namespace is, if you want to reuse the code).
Step 2 – Add the Argument Parser Code
Add a new C# class file called ArgumentParser.cs and copy-paste the code below to the file after deleting the existing code in the page.
Note the namespace and class name, if you have created a different project in Step 1, change the namespace here to reflect the same.
using System;
using System.Collections;
namespace MyTestProject
{
class ArgumentParser
{
#region Parser Methods
//Method which will parse the string input and return a hashtable
public static Hashtable Parse(String[] args)
{
Hashtable argTable = new Hashtable();
try
{
string[] keyvalue;
string value;
if ((null == args) || args.Length == 0)
{
argTable.Add("Invalid", "true");
return argTable;
}
foreach (string s in args)
{
if ((s.StartsWith("-") || s.StartsWith("/")) && (s.Contains("=") && !s.Contains("?")))
{
// Strip off - or /
string key = s.Substring(1, s.Length - 1);
keyvalue = key.Split('=');
key = keyvalue[0].ToString();
value = keyvalue[1].ToString();
if (value == null || value.Trim() == "")
{
argTable.Add("Invalid", "true");
return argTable;
}
AddKeyValuePair(argTable, key, value);
}
else
{
// otherwise this is invalid value
if (s.Contains("?"))
{
AddKeyValuePair(argTable, "?", "true");
}
else
{
AddKeyValuePair(argTable, "Invalid", "true");
}
}
}
// return the hashtable with the command line arguments in it.
return argTable;
}
catch (ArgumentOutOfRangeException outOfRangeEx)
{
Console.WriteLine("Arguments out of range, please check error log" + outOfRangeEx.Message + Environment.NewLine + outOfRangeEx.StackTrace);
return argTable;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
return argTable;
}
}
//Add the arguments in the form of a keyvalue pair to Hashtable
public static void AddKeyValuePair(Hashtable argTable, string key, string value)
{
try
{
if (!argTable.ContainsKey(key))
{
// add this to table
argTable.Add(key, value);
}
else
{
//substitute the value with the latest one
argTable[key] = value;
}
}
catch (ArgumentException argEx)
{
Console.WriteLine(argEx.Message + Environment.NewLine + argEx.StackTrace);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
}
}
#endregion
}
}
Step 3 – Write Code to test the Parser
Now that you have the Argument Parser code in place, switch to your “Program.cs” file which has the Main method. Replace the code in there with the code listing below.
using System;
using System.Collections;
using System.Text;
namespace MyTestProject
{
class Program
{
static void Main(string[] args)
{
StringBuilder usageSyntax = new StringBuilder();
usageSyntax.Append("There was an error while parsing the arguments, please check usage syntax below\n\n");
usageSyntax.Append("MyTestProject -username=praveen -password=dotnetscraps -site=default");
Hashtable myargs = ArgumentParser.Parse(args);
if (myargs.ContainsKey("?") || myargs.ContainsKey("Invalid") || myargs.Count < 3)
{
Console.WriteLine(usageSyntax);
}
else
{
foreach (DictionaryEntry arg in myargs)
{
Console.WriteLine("Key: {0} Value: {1}", arg.Key.ToString(), arg.Value.ToString());
}
}
}
}
}
If you need to pass more than 3 arguments, change the if condition that says myargs.count < 3 and increase the value. If you need to pass any number of arguments, just get rid of that one condition.
And here is how my output looks.
Happy Programming!!!