21

I'm trying to read user arguments in a C# application. I know how to read them based on position with

string[] args = Environment.GetCommandLineArgs();

but I'd like to read them from switches such as

app.exe /f /d:foo

I'm really struggling to find any information on doing this...

MTeck
  • 1,642
  • 3
  • 16
  • 34
  • Unfortunately, C# doesn't give you much more information than simply a list of command-line arguments as strings. It doesn't even include the .exe name. – Kendall Frey Mar 16 '12 at 18:54

8 Answers8

29

Why don't you just parse the array of arguments passed and act based on them, like this

foreach (string arg in args)
{
    switch (arg.Substring(0, 2).ToUpper())
    {
        case "/F":
            // process argument...
            break;
        case "/Z":
            // process arg...
            break;
        case "/D":
            paramD = arg.Substring(3);
            break;
        default:
            // do other stuff...
            break;
    }
}
Micha Wiedenmann
  • 19,979
  • 21
  • 92
  • 137
Jason
  • 3,844
  • 1
  • 21
  • 40
6

I've seen a couple of answers that loop through the args string collection - the problem is you need the next item after you hit the switch you are looking for. I used the array index of the collection in order to get the next item.

In my sample I'm looking for a server and a port /S and /P. I hope this helps someone:

        var server = string.Empty;
        var port = string.Empty;

        for(var x = 0; x < args.Count(); x++)
        {
            switch (args[x].Trim().ToUpper())
            {
                case "/S":
                    server = args[x + 1];
                    break;
                case "/P":
                    port = args[x + 1];
                    break;                                        
            }
        }
Stephen Huff
  • 154
  • 2
  • 9
  • 2
    You'll probably want to advance x after setting the value to the next argument. Otherwise, you'll needlessly process that arg: server = args[++x]; – Baxter Tidwell Sep 23 '17 at 13:56
  • ... but the mentioned `/d:foo` use case isn't caught by your solution – Wolf May 14 '18 at 09:17
4
void Main(string[] args )
{
    foreach( var arg in args )
    {
        // process each arg if needed, i.e., 
        // remove '-', '/', uppercase, whatever
        switch(arg)
        {
            case "blah":
            // ...
        }
    }
}

Libraries do exist for this purpose which make the whole process a lot easier, but if this is a one off app it may not be worth it. Depends on how complex your command line arguments are.

Ed S.
  • 122,712
  • 22
  • 185
  • 265
  • 3
    @MTeck - [Mono.Options](https://github.com/mono/mono/blob/master/mcs/class/Mono.Options/Mono.Options/Options.cs) is a great lightweight example of such a library. – M.Babcock Mar 16 '12 at 19:01
3

What about,

// first is exe of executing program
string[] args = Environment.CommandLine.Split('/').Skip(1).ToArray();
foreach (string arg in args)
{
    string value = arg.Trim();
    switch (value)
    {
        case "f":
            //...
            continue;
    }
    if (value.StartsWith("d:"))
    {
        value = value.Substring(2);
        // ...
        continue;
    }
}
Chuck Savage
  • 11,775
  • 6
  • 49
  • 69
0

Some packages that might be of interest:

  1. Microsoft.Extensions.CommandLineUtils package: https://www.areilly.com/2017/04/21/command-line-argument-parsing-in-net-core-with-microsoft-extensions-commandlineutils/
  2. System.CommandLine package (prerelease at the time of writing): https://learn.microsoft.com/en-us/archive/msdn-magazine/2019/march/net-parse-the-command-line-with-system-commandline
user2173353
  • 4,316
  • 4
  • 47
  • 79
0

Well, basically you already done. Process that string[] array you get from the framework and you done. There is no built-in way to achieve what you're asking for.

Like 3rd parties solution can have a look on

C#/.NET Command Line Arguments Parser

Tigran
  • 61,654
  • 8
  • 86
  • 123
0

I am the author of an open source .NET command-line library that may suit your needs: C# CLI.

You may also want to read this question for other suggestions.

Community
  • 1
  • 1
Bernard
  • 7,908
  • 2
  • 36
  • 33
0

I believe you'll have to roll your own implementation. After writing unit tests to evaluate the new method, I might start thinking along the lines of ...

foreach (string arg in args)
{
    flagF = flagF || arg == "/f"; // assuming F is boolean
    flagD = flagD ?? (arg.Substring(0,3) =="/d:" ? arg.Substring(3) : null);
}
sfuqua
  • 5,797
  • 1
  • 32
  • 33
  • flagF should be initialized to false, then do `flagF |= arg == "/f";` so that once it becomes true, it stays true. The way you have it now, flagF is always true. – Chuck Savage Mar 16 '12 at 19:25
  • then for flagD, in your `()` change the 2 to 3 as `"/d:"` is 3 characters. – Chuck Savage Mar 16 '12 at 19:31
  • @ChuckSavage thanks; the code got the idea across anyway, even if hastily written :-). Correcting now. – sfuqua Mar 19 '12 at 15:48