A reusable, reflection based command-line parser

Originally posted to Shawn Hargreaves Blog on MSDN, Friday, April 20, 2012

I often find myself writing little throwaway utilities to help with other tasks, and many of these utilities need to parse command lines.  There are myriad ways to do this in C#, ranging from the quick and dirty to the infinitely flexible and confusing.  The middle ground approach shown here is not especially unique, but I have found it useful over the years, and thought I would post it here in case you do too.

Get it here.

Use it like so:

    public enum CatSpecies
    {
        Tabby,
        Siamese,
        Alley,
    }


    public class Options
    {
        public int NumberOfCats = 23;
        public CatSpecies Species = CatSpecies.Siamese;
        public bool ChaseTheCats;
        public bool PostToYouTube;
    }


    class Program
    {
        static int Main(string[] args)
        {
            var options = new Options();
            var parser = new CommandLineParser(options);

            if (!parser.ParseCommandLine(args))
                return 1;

            DoStuff(options);

            return 0;
        }
    }

You can run this program like so:

    MyProgram /NumberOfCats:10 /species:alley /posttoyoutube

It automatically generates usage help if you pass invalid values:

    > MyProgram /foo
    Unknown option 'foo'

    Usage: MyProgram

    Options:
        /NumberOfCats:value
        /Species:value
        /ChaseTheCats
        /PostToYouTube

You can mark some options as required:

    public class Options
    {
        [CommandLineParser.Required]
        public int NumberOfCats;

        [CommandLineParser.Required]
        public CatSpecies Species;

        public bool ChaseTheCats;
        public bool PostToYouTube;
    }

Required options are specified without the /ParameterName: prefix:

    MyProgram 10 alley /posttoyoutube

Of course you will get an error if any required parameters are not specified.

The parser also supports list types, which allow a single parameter to be specified more than once (each entry will be appended to the list).  For instance:

    public class Options
    {
        [CommandLineParser.Required]
        public readonly List<string> Names = new List<string>();

        [CommandLineParser.Name("Color")]
        public readonly List<System.Drawing.Color> Colors = new List<System.Drawing.Color>();
    }

This allows you to call:

    MyProgram shawn tracy rhys boo kess finch /color:red /color:white

Note that I was able to specify System.Drawing.Color values by string name (eg. "red").  This works because the parser uses TypeDescriptor/TypeConverter to convert string arguments into whatever types it finds in the Options object.  If you have custom types, just write a matching TypeConverter and you'll be able to specify them directly as argument values.

Enjoy!

Blog index   -   Back to my homepage