A C# Argument Parser for a Windows Console Application

by praveen 1/11/2009 4:13:56 PM

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: -

  1. I need the arguments in a key value pair so i can use them at my leisure.
  2. I wanted to have arguments defined in a key=value format so i know which value matches with what.
  3. 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.

image

 

Happy Programming!!!



blog comments powered by Disqus

Comments

Rahul Soni

Rahul Soni  Twitter

 LinkedIn

 Facebook

 Email me



Vivek Kumbhar

Vivek Kumbhar  Twitter

 LinkedIn

 Facebook

 Email me


Stack Exchange

profile for Vivek at Server Fault, Q&A for system administrators and IT professionals

profile for Rahul Soni at Stack Overflow, Q&A for professional and enthusiast programmers

Calendar

<<  May 2013  >>
MoTuWeThFrSaSu
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789

View posts in large calendar

All Items
Sign in

Visit Microsoft's Site

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.
© Copyright 2013, Rahul Soni

Powered by BlogEngine.NET 1.4.5.0