31

I have a console application called MyTool.exe

What is the simplest way to collect the named arguments passed to this console applicaiton and then to put them in a Dictionarty<string, string>() which will have the argument name as the key and the value as the argument?

for example:

MyTool foo=123432 bar=Alora barFoo=45.9

I should be able to obtain a dictionary which will be:

MyArguments["foo"]=123432 
MyArguments["bar"]="Alora"
MyArguments["barFoo"]="45.9"
Yves M.
  • 29,855
  • 23
  • 108
  • 144
pencilCake
  • 51,323
  • 85
  • 226
  • 363
  • Couldn't you use a more standard format thus allowying your appliction to interop with others better? Have a peek at http://stackoverflow.com/questions/491595/best-way-to-parse-command-line-arguments-in-c – John Mitchell Jul 11 '12 at 09:53

5 Answers5

33

Use this Nuget package

Takes seconds to configure and adds instant professional touch to your application.

// Define a class to receive parsed values
class Options {
  [Option('r', "read", Required = true,
    HelpText = "Input file to be processed.")]
  public string InputFile { get; set; }

  [Option('v', "verbose", DefaultValue = true,
    HelpText = "Prints all messages to standard output.")]
  public bool Verbose { get; set; }

  [ParserState]
  public IParserState LastParserState { get; set; }

  [HelpOption]
  public string GetUsage() {
    return HelpText.AutoBuild(this,
      (HelpText current) => HelpText.DefaultParsingErrorsHandler(this, current));
  }
}

// Consume them
static void Main(string[] args) {
  var options = new Options();
  if (CommandLine.Parser.Default.ParseArguments(args, options)) {
    // Values are available here
    if (options.Verbose) Console.WriteLine("Filename: {0}", options.InputFile);
  }
}
Piotr Kula
  • 9,597
  • 8
  • 59
  • 85
Mrchief
  • 75,126
  • 20
  • 142
  • 189
  • 2.0.*-beta seems to change things a little: https://github.com/gsscoder/commandline - including a different options layout. – WernerCD Jun 15 '16 at 15:14
  • @WernerCD Guess we need to update this answer once it gets released. Thanks for pointing it out. – Mrchief Jun 15 '16 at 15:46
15

Here's how this can be done in the most simple way:

    static void Main(string[] args)
    {
        var arguments = new Dictionary<string, string>();

        foreach (string argument in args)
        {
            string[] splitted = argument.Split('=');

            if (splitted.Length == 2)
            {
                arguments[splitted[0]] = splitted[1];
            }
        }
    }

Note that:

  • Argument names are case sensitive
  • Providing the same argument name more than once does not produce an error
  • No spaces are allowed
  • One = sign must be used
Kay Zed
  • 1,304
  • 2
  • 21
  • 31
  • Overwriting a key is a deadly type of "silent error". The program does not complain, and misinterprets what the user specifies. Granted for the majority of cases it won't matter. – hova Jul 13 '12 at 18:31
  • hova: this serves as an example. – Kay Zed Jul 13 '12 at 19:10
  • This is my approach, as well. I like the concept of using "pure" C# and .NET as opposed to third-party libs, when viable. – Christiano Kiss Jan 08 '21 at 13:14
4

if you have a "=" in your parameter values, a safer option would be:

private static Dictionary<string, string> ResolveArguments(string[] args)
{
    if (args == null)
        return null;

    if (args.Length > 0)
    {
        var arguments = new Dictionary<string, string>();
        foreach (string argument in args)
        {
            int idx = argument.IndexOf('=');
            if (idx > 0)
                arguments[argument.Substring(0, idx)] = argument.Substring(idx+1);
        }
        return arguments;
    }

    return null;
}
Matas Vaitkevicius
  • 58,075
  • 31
  • 238
  • 265
  • 2
    It seems to me that instead of "if (args.Length > 1)", you should have "if (args.Length >= 1)" or "if (args.Length > 0)". In the case of exactly 1 argument, your code returns null. – Cityonhill93 Oct 09 '17 at 16:34
2

I don't see why this code is bad? hova?

        var arguments = new Dictionary<string, string>();
        foreach (var item in Environment.GetCommandLineArgs())
        {
            try
            {
                var parts = item.Split('=');
                arguments.Add(parts[0], parts[1]);
            }
            catch (Exception ex)
            {
                // your error handling here....
            }
Stig
  • 1,323
  • 16
  • 22
0

You can use Microsoft.Extensions.Configuration.CommandLine.

IConfiguration configuration = new ConfigurationBuilder()
    .AddJsonFile("appsettings.json", optional: true)
    .AddEnvironmentVariables()
    .AddCommandLine(args) // here
    .Build();

Than you can execute your app like this:

MyConsoleApplication.exe --myParameterName myvalue

Check this blog post and docs for details.

Jonatan Dragon
  • 4,675
  • 3
  • 30
  • 38