Best way to parse command line arguments in C#?

C#.NetCommand Line-Arguments

C# Problem Overview


When building console applications that take parameters, you can use the arguments passed to Main(string[] args).

In the past I've simply indexed/looped that array and done a few regular expressions to extract the values. However, when the commands get more complicated, the parsing can get pretty ugly.

So I'm interested in:

  • Libraries that you use
  • Patterns that you use

Assume the commands always adhere to common standards such as answered here.

C# Solutions


Solution 1 - C#

I would strongly suggest using NDesk.Options (Documentation) and/or Mono.Options (same API, different namespace). An example from the documentation:

bool show_help = false;
List<string> names = new List<string> ();
int repeat = 1;
 
var p = new OptionSet () {
    { "n|name=", "the {NAME} of someone to greet.",
       v => names.Add (v) },
    { "r|repeat=", 
       "the number of {TIMES} to repeat the greeting.\n" + 
          "this must be an integer.",
        (int v) => repeat = v },
    { "v", "increase debug message verbosity",
       v => { if (v != null) ++verbosity; } },
    { "h|help",  "show this message and exit", 
       v => show_help = v != null },
};

List<string> extra;
try {
    extra = p.Parse (args);
}
catch (OptionException e) {
    Console.Write ("greet: ");
    Console.WriteLine (e.Message);
    Console.WriteLine ("Try `greet --help' for more information.");
    return;
}

Solution 2 - C#

I really like the Command Line Parser Library ( http://commandline.codeplex.com/ ). It has a very simple and elegant way of setting up parameters via attributes:

class Options
{
    [Option("i", "input", Required = true, HelpText = "Input file to read.")]
    public string InputFile { get; set; }

    [Option(null, "length", HelpText = "The maximum number of bytes to process.")]
    public int MaximumLenght { get; set; }

    [Option("v", null, HelpText = "Print details during execution.")]
    public bool Verbose { get; set; }

    [HelpOption(HelpText = "Display this help screen.")]
    public string GetUsage()
    {
        var usage = new StringBuilder();
        usage.AppendLine("Quickstart Application 1.0");
        usage.AppendLine("Read user manual for usage instructions...");
        return usage.ToString();
    }
}

Solution 3 - C#

The WPF TestApi library comes with one of the nicest command line parsers for C# development. I highly recommend looking into it, from Ivo Manolov's blog on the API:

// EXAMPLE #2:
// Sample for parsing the following command-line:
// Test.exe /verbose /runId=10
// This sample declares a class in which the strongly-
// typed arguments are populated
public class CommandLineArguments
{
   bool? Verbose { get; set; }
   int? RunId { get; set; }
}

CommandLineArguments a = new CommandLineArguments();
CommandLineParser.ParseArguments(args, a);

Solution 4 - C#

Solution 5 - C#

Looks like everybody has their own pet command-line parsers, figure I had better add mine as well :).

http://bizark.codeplex.com/

This library contains a command-line parser that will initialize a class with the values from the command-line. It has a ton of features (I've been building it up over many years).

From the documentation...

Command-line parsing in the BizArk framework has these key features:

  • Automatic initialization: Class properties are automatically set based on the command-line arguments.
  • Default properties: Send in a value without specifying the property name.
  • Value conversion: Uses the powerful ConvertEx class also included in BizArk to convert values to the proper type.
  • Boolean flags: Flags can be specified by simply using the argument (ex, /b for true and /b- for false) or by adding the value true/false, yes/no, etc.
  • Argument arrays: Simply add multiple values after the command-line name to set a property that is defined as an array. Ex, /x 1 2 3 will populate x with the array { 1, 2, 3 } (assuming x is defined as an array of integers).
  • Command-line aliases: A property can support multiple command-line aliases for it. For example, Help uses the alias ?.
  • Partial name recognition: You don’t need to spell out the full name or alias, just spell enough for the parser to disambiguate the property/alias from the others.
  • Supports ClickOnce: Can initialize properties even when they are specified as the query string in a URL for ClickOnce deployed applications. The command-line initialization method will detect if it is running as ClickOnce or not so your code doesn’t need to change when using it.
  • Automatically creates /? help: This includes nice formatting that takes into account the width of the console.
  • Load/Save command-line arguments to a file: This is especially useful if you have multiple large, complex sets of command-line arguments that you want to run multiple times.

Solution 6 - C#

I wrote a C# command line argument parser a while back. Its at: http://www.codeplex.com/CommandLineArguments

Solution 7 - C#

CLAP (command line argument parser) has a usable API and is wonderfully documented. You make a method, annotating the parameters. https://github.com/adrianaisemberg/CLAP

Solution 8 - C#

There are numerous solutions to this problem. For completeness and to provide the alternative if someone desires I'm adding this answer for two useful classes in my google code library.

The first is ArgumentList which is responsible only for parsing command line parameters. It collects name-value pairs defined by switches '/x:y' or '-x=y' and also collects a list of 'unnamed' entries. It's basic usage is discussed here, view the class here.

The second part of this is the CommandInterpreter which creates a fully-functional command-line application out of your .Net class. As an example:

using CSharpTest.Net.Commands;
static class Program
{
    static void Main(string[] args)
    {
        new CommandInterpreter(new Commands()).Run(args);
    }
    //example ‘Commands’ class:
    class Commands
    {
        public int SomeValue { get; set; }
        public void DoSomething(string svalue, int ivalue)
        { ... }

With the above example code you can run the following:

> Program.exe DoSomething "string value" 5

-- or --

> Program.exe dosomething /ivalue=5 -svalue:"string value"

It's as simple as that or as complex as you need it to be. You can review the source code, view the help, or download the binary.

Solution 9 - C#

I like that one, because you can "define rules" for the arguments, needed or not,...

or if you're a Unix guy, than you might like the GNU Getopt .NET port.

Solution 10 - C#

You may like my one [Rug.Cmd][1]

Easy to use and expandable command line argument parser. Handles: Bool, Plus / Minus, String, String List, CSV, Enumeration.

Built in '/?' help mode.

Built in '/??' and '/?D' document generator modes.

static void Main(string[] args) 
{            
    // create the argument parser
    ArgumentParser parser = new ArgumentParser("ArgumentExample", "Example of argument parsing");

    // create the argument for a string
    StringArgument StringArg = new StringArgument("String", "Example string argument", "This argument demonstrates string arguments");

    // add the argument to the parser 
    parser.Add("/", "String", StringArg);
        
    // parse arguemnts
    parser.Parse(args);

    // did the parser detect a /? argument 
    if (parser.HelpMode == false) 
    {
        // was the string argument defined 
        if (StringArg.Defined == true)
        {
            // write its value
            RC.WriteLine("String argument was defined");
            RC.WriteLine(StringArg.Value);
        }
    }
}

Edit: This is my project and as such this answer should not be seen as an endorsement from a third party. That said I do use it for every command line based program I write, it is open source and it is my hope that others may benefit from it. [1]: http://cmd.codeplex.com

Solution 11 - C#

There is a command line argument parser at http://www.codeplex.com/commonlibrarynet

It can parse arguments using

  1. attributes
  2. explicit calls
  3. single line of multiple arguments OR string array

It can handle things like the following:

-config:Qa -startdate:${today} -region:'New York' Settings01

It's very easy to use.

Solution 12 - C#

This is a handler I wrote based on the Novell Options class.

This one is aimed at console applications that execute a while (input !="exit") style loop, an interactive console such as an FTP console for example.

Example usage:

static void Main(string[] args)
{
	// Setup
	CommandHandler handler = new CommandHandler();
	CommandOptions options = new CommandOptions();

	// Add some commands. Use the v syntax for passing arguments
	options.Add("show", handler.Show)
		.Add("connect", v => handler.Connect(v))
		.Add("dir", handler.Dir);

	// Read lines
	System.Console.Write(">");
	string input = System.Console.ReadLine();

	while (input != "quit" && input != "exit")
	{
		if (input == "cls" || input == "clear")
		{
			System.Console.Clear();
		}
		else
		{
			if (!string.IsNullOrEmpty(input))
			{
				if (options.Parse(input))
				{
					System.Console.WriteLine(handler.OutputMessage);
				}
				else
				{
					System.Console.WriteLine("I didn't understand that command");
				}

			}
			
		}

		System.Console.Write(">");
		input = System.Console.ReadLine();
	}
}

And the source:

/// <summary>
/// A class for parsing commands inside a tool. Based on Novell Options class (http://www.ndesk.org/Options).
/// </summary>
public class CommandOptions
{
	private Dictionary<string, Action<string[]>> _actions;
	private Dictionary<string, Action> _actionsNoParams;

	/// <summary>
	/// Initializes a new instance of the <see cref="CommandOptions"/> class.
	/// </summary>
	public CommandOptions()
	{
		_actions = new Dictionary<string, Action<string[]>>();
		_actionsNoParams = new Dictionary<string, Action>();
	}

	/// <summary>
	/// Adds a command option and an action to perform when the command is found.
	/// </summary>
	/// <param name="name">The name of the command.</param>
	/// <param name="action">An action delegate</param>
	/// <returns>The current CommandOptions instance.</returns>
	public CommandOptions Add(string name, Action action)
	{
		_actionsNoParams.Add(name, action);
		return this;
	}

	/// <summary>
	/// Adds a command option and an action (with parameter) to perform when the command is found.
	/// </summary>
	/// <param name="name">The name of the command.</param>
	/// <param name="action">An action delegate that has one parameter - string[] args.</param>
	/// <returns>The current CommandOptions instance.</returns>
	public CommandOptions Add(string name, Action<string[]> action)
	{
		_actions.Add(name, action);
		return this;
	}

	/// <summary>
	/// Parses the text command and calls any actions associated with the command.
	/// </summary>
	/// <param name="command">The text command, e.g "show databases"</param>
	public bool Parse(string command)
	{
		if (command.IndexOf(" ") == -1)
		{
			// No params
			foreach (string key in _actionsNoParams.Keys)
			{
				if (command == key)
				{
					_actionsNoParams[key].Invoke();
					return true;
				}
			}
		}
		else
		{
			// Params
			foreach (string key in _actions.Keys)
			{
				if (command.StartsWith(key) && command.Length > key.Length)
				{
					
					string options = command.Substring(key.Length);
					options = options.Trim();
					string[] parts = options.Split(' ');
					_actions[key].Invoke(parts);
					return true;
				}
			}
		}

		return false;
	}
}

Solution 13 - C#

My personal favorite is http://www.codeproject.com/KB/recipes/plossum_commandline.aspx by Peter Palotas:

[CommandLineManager(ApplicationName="Hello World",
    Copyright="Copyright (c) Peter Palotas")]
class Options
{
   [CommandLineOption(Description="Displays this help text")]
   public bool Help = false;

   [CommandLineOption(Description = "Specifies the input file", MinOccurs=1)]
   public string Name
   {
      get { return mName; }
      set
      {
         if (String.IsNullOrEmpty(value))
            throw new InvalidOptionValueException(
                "The name must not be empty", false);
         mName = value;
      }
   }

   private string mName;
}

Solution 14 - C#

I recently came across The FubuCore Command line parsing implementation I really like it, the reasons being:

  • it's easy to use - although I couldn't find a documentation for it, the FubuCore solution also provides a project containing a nice set of Unit Tests that speak more about the functionality than any documentation could
  • it has a nice object oriented design, no code repetition or other such things that I used to have in my command line parsing apps
  • it's declarative: you basically write classes for the Commands and sets of parameters and decorate them with attributes to set various options (e.g. name, description, mandatory/optional)
  • the library even prints a nice Usage Graph, based on these definitions

Below is a simple example on how to use this. To illustrate the usage, I've written a simple utility that has two commands:

  • add (adds an object to a list - an object consists of a name(string), value(int) and a boolean flag)
  • list (lists all the currently added objects)

First of all, I wrote a Command class for the 'add' command:

[Usage("add", "Adds an object to the list")]
[CommandDescription("Add object", Name = "add")]
public class AddCommand : FubuCommand<CommandInput>
{
    public override bool Execute(CommandInput input)
    {
        State.Objects.Add(input); // add the new object to an in-memory collection

        return true;
    }
}

This command takes a CommandInput instance as parameter, so I define that next:

public class CommandInput
{
    [RequiredUsage("add"), Description("The name of the object to add")]
    public string ObjectName { get; set; }

    [ValidUsage("add")]
    [Description("The value of the object to add")]
    public int ObjectValue { get; set; }

    [Description("Multiply the value by -1")]
    [ValidUsage("add")]
    [FlagAlias("nv")]
    public bool NegateValueFlag { get; set; }
}

The next command is 'list', which is implemented as follows:

[Usage("list", "List the objects we have so far")]
[CommandDescription("List objects", Name = "list")]
public class ListCommand : FubuCommand<NullInput>
{
    public override bool Execute(NullInput input)
    {
        State.Objects.ForEach(Console.WriteLine);

        return false;
    }
}

The 'list' command takes no parameters, so I defined a NullInput class for this:

public class NullInput { }

All that's left now is to wire this up in the Main() method, like this:

    static void Main(string[] args)
    {
        var factory = new CommandFactory();
        factory.RegisterCommands(typeof(Program).Assembly);

        var executor = new CommandExecutor(factory);

        executor.Execute(args);
    }

The program works as expected, printing hints about the correct usage in case any commands are invalid:

  ------------------------
    Available commands:
  ------------------------
     add -> Add object
    list -> List objects
  ------------------------

And a sample usage for the 'add' command:

Usages for 'add' (Add object)
  add <objectname> [-nv]

  -------------------------------------------------
    Arguments
  -------------------------------------------------
     objectname -> The name of the object to add
    objectvalue -> The value of the object to add
  -------------------------------------------------

  -------------------------------------
    Flags
  -------------------------------------
    [-nv] -> Multiply the value by -1
  -------------------------------------

Solution 15 - C#

Powershell Commandlets.

Parsing done by powershell based on attributes specified on the commandlets, support for validations, parameter sets, pipelining, error reporting, help, and best of all returning .NET objects for use in other commandlets.

A couple links i found helpful getting started:

Solution 16 - C#

C# CLI is a very simple command-line argument parsing library that I wrote. It's well-documented and open source.

Solution 17 - C#

Genghis Command Line Parser may be a little out of date, but it is very feature complete and works pretty well for me.

Solution 18 - C#

I would suggest the open-source library CSharpOptParse. It parses the command line and hydrates a user-defined .NET object with the command-line input. I always turn to this library when writing a C# console application.

Solution 19 - C#

Please use the .net port of the apache commons cli API. This works great.

http://sourceforge.net/projects/dotnetcli/

and the original API for concepts and introduction

http://commons.apache.org/cli/

Solution 20 - C#

A very simple easy to use ad hoc class for command line parsing, that supports default arguments.

class CommandLineArgs
{
    public static CommandLineArgs I
    {
        get
        {
            return m_instance;
        }
    }

    public	string argAsString( string argName )
    {
        if (m_args.ContainsKey(argName)) {
            return m_args[argName];
        }
        else return "";
    }

    public long argAsLong(string argName)
    {
        if (m_args.ContainsKey(argName))
        {
            return Convert.ToInt64(m_args[argName]);
        }
        else return 0;
    }

    public double argAsDouble(string argName)
    {
        if (m_args.ContainsKey(argName))
        {
            return Convert.ToDouble(m_args[argName]);
        }
        else return 0;
    }

    public void parseArgs(string[] args, string defaultArgs )
    {
        m_args = new Dictionary<string, string>();
        parseDefaults(defaultArgs );

        foreach (string arg in args)
        {
            string[] words = arg.Split('=');
            m_args[words[0]] = words[1];
        }
    }

    private void parseDefaults(string defaultArgs )
    {
        if ( defaultArgs == "" ) return;
        string[] args = defaultArgs.Split(';');

        foreach (string arg in args)
        {
            string[] words = arg.Split('=');
            m_args[words[0]] = words[1];
        }
    }

    private Dictionary<string, string> m_args = null;
    static readonly CommandLineArgs m_instance = new CommandLineArgs();
}

class Program
{
    static void Main(string[] args)
    {
        CommandLineArgs.I.parseArgs(args, "myStringArg=defaultVal;someLong=12");
        Console.WriteLine("Arg myStringArg  : '{0}' ", CommandLineArgs.I.argAsString("myStringArg"));
        Console.WriteLine("Arg someLong     : '{0}' ", CommandLineArgs.I.argAsLong("someLong"));
    }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPaul StovellView Question on Stackoverflow
Solution 1 - C#jonpView Answer on Stackoverflow
Solution 2 - C#Adrian GrigoreView Answer on Stackoverflow
Solution 3 - C#user7116View Answer on Stackoverflow
Solution 4 - C#abatishchevView Answer on Stackoverflow
Solution 5 - C#BrianView Answer on Stackoverflow
Solution 6 - C#PeterHView Answer on Stackoverflow
Solution 7 - C#Colonel PanicView Answer on Stackoverflow
Solution 8 - C#csharptest.netView Answer on Stackoverflow
Solution 9 - C#Xn0vv3rView Answer on Stackoverflow
Solution 10 - C#Phill TewView Answer on Stackoverflow
Solution 11 - C#jeromeView Answer on Stackoverflow
Solution 12 - C#Chris SView Answer on Stackoverflow
Solution 13 - C#Raphael BossekView Answer on Stackoverflow
Solution 14 - C#Cristian LupascuView Answer on Stackoverflow
Solution 15 - C#hannasmView Answer on Stackoverflow
Solution 16 - C#BernardView Answer on Stackoverflow
Solution 17 - C#devdimiView Answer on Stackoverflow
Solution 18 - C#Stuart LangeView Answer on Stackoverflow
Solution 19 - C#AndreasView Answer on Stackoverflow
Solution 20 - C#Martin LütkenView Answer on Stackoverflow