Best Way to Parse Command Line Arguments in C#

Best way to parse command line arguments in 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;
}

Using Command Line to parse arguments

static void Main(string[] args)
{
Parser.Default.ParseArguments<CommandLineOptions>(args)
.WithParsed<CommandLineOptions>(o =>
{
Console.WriteLine(o.Symbol);
Console.WriteLine(o.Date);
});
...
}

public class CommandLineOptions
{
[Option('s', "symbol", Required = true, HelpText = "Symbol To run backtest")]
public string Symbol { get; set; }

[Option('d', "date", Required = true)]
public string Date { get; set; }

}

Looking for a Command Line Argument Parser for .NET

My personal favourite 3rd party commandline parsing library is Command Line Parser and I assume this is the one you are referring to. The most recent release was less than 2 months ago and there are regular commits. If you want a more mature offering you could check out the console library in the mono project (sorry I can't seem to find a direct link to the namespace at the moment, but its a part of the mono framework)

Parse commandline args and execute methods

UltraMapper.CommandLine does exactly what you want!

It allows you to call methods directly from commandline passing as many input parameters as you want.

It supports primitive and complex types as arguments; Collections as IEnumerable, List and arrays are also supported.

It allows you to drastically reduce the amount of code needed to deal with commandline args by getting rid of all the 'commandline flags' and dispatch code.

public class Program
{
static void Main( string[] args )
{
CommandLine.Instance.Parse<Commands>( args );
//just call with this args: --method1 ["my string" "mysecondstring" "etc"]
}

public class Commands
{
public void Method1( List<string> strings ) { ///... }
public void Method2( SomeClass myParam, List<SomeOtherClass> mySecondParam ) { ///... }
}
}

I released UltraMapper.CommandLine as an open source project on github.

Check it out, it might be helpful on your next project!

There’s also nuget package available here

How to parse command line arguments

UPDATE: Update to handle colons in setting values.

OK, so here you run into one of the implicit defaults of NDesk.Options, which is that in multivalued parameters, both : and = are considered as value separators, meaning that Setting=C:\Path parses as 3 values (Setting, C, \Path) instead of your expected two.

In order to fix that, you simply have to modify the -s option definition to only consider = as a valid separator, by writing "s={=}" instead of "s=".

Original answer, when it was about backslashes.

I have used NDesk.Options, without encountering any issues with quoted paths and backslashes.

Here is my sample program:

public static void Main(string[] args)
{
string parsedPath = null;
Dictionary<string, string> parsedValues = new Dictionary<string, string>();
var set = new OptionSet()
{
{ "p=", "the project path", v => parsedPath = v },
{ "s=", "a setting", (m, v) => { parsedValues.Add(m, v); } },
};
set.Parse(args);
Console.WriteLine(parsedPath ?? "<NULL>");
foreach (var keyValuePair in parsedValues)
{
Console.WriteLine(keyValuePair.Key + "::::" + keyValuePair.Value);
}
}

You will see that there is a difference between your definition and mine: p= means that the option has a required value, while your definition means that p is a boolean flag value.

I have not run with any problem concerning backslashes, either in the p setting or in the s setting. Could you try running the program with version 0.2.1 of NDesk.Options and show which values fail?

Here are some samples that I ran, which all parsed successfully:

-p=..\Path
-p..\Path
-pC:\Hello
-pHello\World
-p"Hello\World"
-s"Greeting=Hello\World"
-sGreeting="Hello\World"
-sGreeting=Hello\World
-sGreeting="Hello\My World"
-s"Greeting=Hello\My World"

Here are some parses which do produce another result that deserve mention:

-sGreeting=Hello\My World -- // This gives Greeting="Hello\My" 

Note: If that changes anything, I ran NDesk.Options with the Options.cs source code file in the project, not with the compiled DLL.



Related Topics



Leave a reply



Submit