Click here to Skip to main content
Click here to Skip to main content

C#/.NET Command Line Argument Parser Reloaded

By , 9 Sep 2011
 

Introduction

Many programs use command line arguments. Each time parsing has to be done in the same way. There are other projects which facilitate the parsing process. For example, C#/.NET Command Line Arguments Parser does a great job, however it lacks verification of the passed and parsed arguments. C# command-line option parser can do that, however using it is quite complicated. CLAParser is a compromise of both: It is easy to use and uses regular expressions for parsing and validating which makes it quite powerful. Further more, it supports i18n and it creates information for correct command line usage for the user.

Naming Conventions

  • Arguments: Everything passed on argument line to program separated by spaces, or grouped by quotes, e.g.
    program.exe argument1 /argument2 
    	--argument3 .!§$argument4´ß2! "argument5 with spaces"
  • Parameter: All arguments that start with / or -, e.g.
    program.exe /parameter1 -parameter2
  • Values: Every argument that is not a parameter, e.g.
    program.exe value1 value2 /my_param  'v a l u e 3'

In the last example, value1 and value2 are values without parameters, whereas v a l u e 3 belongs to parameter my_param. (Note that the single quotes which hold 'v a l u e 3' together are removed by CLAParser.)

Using the Code

  1. Copy CLAParser files to your project folder and include them in C# project (CmdLineArgumentParser.cs, CmdLineArgumentParserRes.resx, and optionally further resx-files).

    project explorer

  2. Create a CLAParser instance by calling the constructor.
    CLAParser.CLAParser CmdLine = new CLAParser.CLAParser("CLAParserTest");
    The argument must be the default namespace. (This is necessary so that CLAParser can find its resx-files.)
  3. Use CmdLine.Parameter() function to define known parameters.
    CmdLine.Parameter(CLAParser.CLAParser.ParamAllowType.Optional,
        "", CLAParser.CLAParser.ValueType.String,
        "Path to file that is to be loaded on starting the program.");
    CmdLine.Parameter(CLAParser.CLAParser.ParamAllowType.Optional,
        "output", CLAParser.CLAParser.ValueType.OptionalString,
        "Write output to file, if no file specified default file output.txt is used.");
    CmdLine.Parameter(CLAParser.CLAParser.ParamAllowType.Required, "add",
        CLAParser.CLAParser.ValueType.MultipleInts,
        "Do a mathematical addition of number given integers.");
  4. Start parsing by calling function CmdLine.Parse(). Raised exceptions can be passed directly to the user. They indicate the reason for the problem. Further, show user correct syntax and information about the parameters using CmdLine.GetUsage() and CmdLine.GetParameterInfo().
    try
    {
        CmdLine.Parse();
    }
    catch (CLAParser.CLAParser.CmdLineArgumentException Ex)
    {
        Console.WriteLine(Ex.Message);
        Console.WriteLine(CmdLine.GetUsage());
        Console.WriteLine(CmdLine.GetParameterInfo());
    }
  5. If arguments are correct and all required arguments are defined, no exception is raised and values of all parameters can be accessed by the dictionary interface. Optional parameters which are not defined by the user are indicated by null values. A value without parameter can be accessed by the empty string ("").
    if(CmdLine[""] != null)
    {
        value = CmdLine[""];
        ...
    }
    if(CmdLine["parameter"] != null)
    {
        value = CmdLine["parameter"];
        ...
    }

Points of Interest

  • Update: Using the obsolete function Parse(string[] Arguments) with args as parameter quotes (") must be escaped (\") to be recognized correctly. It is recommended to use function Parse() instead!
  • Function FindMismatchReasonInRegex() helps in analyzing why a search string does not match a regular expression and indicates where the problem probably is located.
  • CLAParser is internationalized, i.e. new languages can easily be defined by creating new resx-files (localization).
  • Using the enumerator, all arguments can be traversed, e.g.:
    IEnumerator e = CmdLine.GetEnumerator();
    while (e.MoveNext())
    {
        DictionaryEntry arg = (DictionaryEntry)e.Current;
        Console.WriteLine(arg.Key + "=" + arg.Value);
    }
  • For a complete overview of CLAParser's capabilities, have a look at the attached code files.

History

  • 2010-02-24
    • Initial release
  • 2010-04-05
    • CmdLineArgumentParser.cs:574 -> from "...Parameters == false)" to "...Parameters == true)"
  • 2011-01-06
    • Corrected error in regular expression which made it impossible to use more than one quoted value
    • Added internal function GetRawCommandlineArgs() proposed by vermis0. Together with it comes function Parse() which makes function Parse(string[] Arguments) obsolete. Now the quotes of quoted values (e.g. "value with spaces") do not need to be escaped anymore!
  • 2011-01-07
    • Corrected error in regular expression which made it impossible to use a value without parameter containing minus (-) or slash (/).
    • Made behaviour with (first) value without parameter more consistent. Instead of setting AllowValuesWithoutParameter, use function Parameter() with ParameterName=="".
    • Fixed error with case sensitivity of parameter. Now everything is case insensitive.
  • 2011-09-09
    • Corrected problem reported by Hautzendorfer concerning single parameters not being processed correctly

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Julian Ohrt
United States United States
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
SuggestionSimple Command Line Arguments ParsermemberMember 14778522 Mar '12 - 5:31 
QuestionSomething more FunctionalmemberAlois Kraus9 Sep '11 - 12:26 
AnswerRe: Something more FunctionalmemberJulian Ohrt9 Sep '11 - 23:47 
GeneralRe: Something more FunctionalmemberAlois Kraus9 Sep '11 - 23:58 
GeneralIsn't there a problem ...memberHautzendorfer23 May '11 - 9:54 
GeneralRe: Isn't there a problem ...memberJulian Ohrt9 Sep '11 - 2:55 
QuestionFxCop CompliancememberDave Hary8 Jan '11 - 8:13 
AnswerRe: FxCop Compliancememberleppie9 Jan '11 - 23:04 
AnswerRe: FxCop CompliancememberJulian Ohrt9 Sep '11 - 2:59 
GeneralSuggestion on using Environment.CommandLinemembervermis06 Dec '10 - 9:53 
GeneralRe: Suggestion on using Environment.CommandLinememberHeinz JKarl Otta Fritz6 Jan '11 - 3:11 
GeneralWorks greatmemberssm629716 Jul '10 - 6:21 
QuestionWhat about...memberkornman005 Mar '10 - 5:40 
AnswerRe: What about...memberMarkLTX5 Mar '10 - 6:33 
GeneralRe: What about...memberkornman005 Mar '10 - 7:16 
GeneralRe: What about...memberHeinz JKarl Otta Fritz5 Apr '10 - 3:09 
GeneralI like what you have done, but alas someone beat you to itmvpSacha Barber5 Mar '10 - 1:18 
GeneralRe: I like what you have done, but alas someone beat you to itmemberHeinz JKarl Otta Fritz5 Apr '10 - 3:16 
Thanks for your reply! I think I even stumbled over that one before. However it lacks verification of the passed and parsed arguments. At least I do not see how to define which parameters are optional and which are required. That is why I wanted to make my own (for my feeling) more intuitive parser.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130516.1 | Last Updated 9 Sep 2011
Article Copyright 2010 by Julian Ohrt
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid