views:

75

answers:

7

A lot of command line utilities use parameters, such as:

gacutil /i MyDLL.dll

or

regasm /tlb:MyDll.tlb MyDll.dll

How do I set up a .NET console application to take in command line arguments and, secondarily, how can you emulate handling "option" parameters like /i and /tlb: in the respective examples above?

+1  A: 

You just make your Main method take a string[] parameter:

class Test
{
    static void Main(string[] args)
    {
        foreach (string arg in args)
        {
            Console.WriteLine(arg);
        }
    }
}

It's up to you to parse the arguments appropriately, in that there's nothing built into the framework to do it. You might want to look at the NDesk.Options library though. (There are plenty of others, but that seems to be a popular one. I can't say I've used it myself, mind you.)

Jon Skeet
+4  A: 

There is a good explanation at http://stackoverflow.com/questions/491595/best-way-to-parse-command-line-arguments-in-c

jrbjazz
+5  A: 

You declare a parameter for the Main method:

public static void Main(string[] args)

Now you have an array that for your first example contains:

args[0] = "/i"
args[1] = "MyDLL.dll"

You just have to parse the strings to determine what the parameter means. Something along the lines of:

foreach (sting cmd in args) {
  if (cmd.StartsWith("/")) {
    switch (cmd.Substring(1)) {
      case "i":
        // handle /i parameter
        break;
      // some more options...
      default:
        // unknown parameter
        break;
    }
  } else {
    // cmd is the filename
  }
}
Guffa
This ended up working for my simple solution, but I modified the switch statement a little (and is in VB.NET): `cmd.Substring(1, cmd.Length - 1).Split(New Char() {":"c}, StringSplitOptions.RemoveEmptyEntries)(0).ToLower()`. That way I can use a full word as an option parameter.
Ben McCormack
A: 

This page has a VB.NET example

Sub Main()
    Dim arrArgs() A s String = Command.Split(“,”)
    Dim i As Integer
    Console.Write(vbNewLine & vbNewLine)
    If arrArgs(0) <> Nothing Then
        For i = LBound(arrArgs) To UBound(arrArgs)
            Console.Write(“Parameter “ & i & ” is “ & arrArgs(i) & vbNewLine)
        Next
    Else
        Console.Write(“No parameter passed”)
    End If
    Console.Write(vbNewLine & vbNewLine)
End Sub

This MSDN page has a C# example:

static int Main(string[] args)
{
    // Test if input arguments were supplied:
    if (args.Length == 0)
    {
        System.Console.WriteLine("Please enter a numeric argument.");
        System.Console.WriteLine("Usage: Factorial <num>");
        return 1;
    }

    // Try to convert the input arguments to numbers. This will throw
    // an exception if the argument is not a number.
    // num = int.Parse(args[0]);
    int num;
    bool test = int.TryParse(args[0], out num);
    if (test == false)
    {
        System.Console.WriteLine("Please enter a numeric argument.");
        System.Console.WriteLine("Usage: Factorial <num>");
        return 1;
    }
.....
ChrisF
A: 

The entry point of the application can be declared as:

static void Main (string[] args) { ... }

This gives you an array of strings in which each element is one of the command line parameters. Once you've got that it's just a matter of parsing the strings in the array to configure the options in your app.

Andrew Cooper
A: 

You need to handle this by yourself (or use an existing library) to deal with command line parameters. See MSDN (Main() and Command-Line Arguments).

One good library is Mono.Options, another one I have used is commandline.

In your console app, you will have a main method that takes a string[] parameter (by default and convention) this is named args. This array contains all the command line parameters. You can then parse these out.

Oded
A: 

I tend to write my own logic for this, since I usually don't want to create an additional external dependency for my console application.

Below is some code that I wrote to populate some variables using the command line arguments. This code is intended to support prefixing parameter names with either "/" or "-" and, if the parameter takes a value (i.e. it's not a flag), supports separating the value from the name by either ":" or " ".

Please excuse the lack of comments ;)

    static void Main(string[] args)
    {
        string directory = null;
        string filePattern = null;
        string sourceDirectory = null;
        string targetDirectory = null;
        List<string> version = null;
        string action = null;
        bool showHelp = false;

        for (int i = 0; i < args.Length; i++)
        {
            string parameterName;
            int colonIndex = args[i].IndexOf(':');
            if (colonIndex >= 0)
                parameterName = args[i].Substring(0, colonIndex);
            else
                parameterName = args[i];
            switch (parameterName.ToLower())
            {
                case "-dir":
                case "/dir":
                    if (colonIndex >= 0)
                    {
                        int valueStartIndex = colonIndex + 1;
                        directory = args[i].Substring(valueStartIndex, args[i].Length - valueStartIndex);
                    }
                    else
                    {
                        i++;
                        if (i < args.Length)
                        {
                            directory = args[i];
                        }
                        else
                        {
                            System.Console.WriteLine("Expected a directory to be specified with the dir parameter.");
                        }
                    }
                    break;
                case "-sourcedir":
                case "/sourcedir":
                    if (colonIndex >= 0)
                    {
                        int valueStartIndex = colonIndex + 1;
                        sourceDirectory = args[i].Substring(valueStartIndex, args[i].Length - valueStartIndex);
                    }
                    else
                    {
                        i++;
                        if (i < args.Length)
                        {
                            sourceDirectory = args[i];
                        }
                        else
                        {
                            System.Console.WriteLine("Expected a directory to be specified with the sourcedir parameter.");
                        }
                    }
                    break;
                case "-targetdir":
                case "/targetdir":
                    if (colonIndex >= 0)
                    {
                        int valueStartIndex = colonIndex + 1;
                        targetDirectory = args[i].Substring(valueStartIndex, args[i].Length - valueStartIndex);
                    }
                    else
                    {
                        i++;
                        if (i < args.Length)
                        {
                            targetDirectory = args[i];
                        }
                        else
                        {
                            System.Console.WriteLine("Expected a directory to be specified with the targetdir parameter.");
                        }
                    }
                    break;
                case "-file":
                case "/file":
                    if (colonIndex >= 0)
                    {
                        int valueStartIndex = colonIndex + 1;
                        filePattern = args[i].Substring(valueStartIndex, args[i].Length - valueStartIndex);
                    }
                    else
                    {
                        i++;
                        if (i < args.Length)
                        {
                            filePattern = args[i];
                        }
                        else
                        {
                            System.Console.WriteLine("Expected a file pattern to be specified with the file parameter.");
                            return;
                        }
                    }
                    break;
                case "-action":
                case "/action":
                    if (colonIndex >= 0)
                    {
                        int valueStartIndex = colonIndex + 1;
                        action = args[i].Substring(valueStartIndex, args[i].Length - valueStartIndex);
                    }
                    else
                    {
                        i++;
                        if (i < args.Length)
                        {
                            action = args[i];
                        }
                        else
                        {
                            System.Console.WriteLine("Expected an action to be specified with the action parameter.");
                            return;
                        }
                    }
                    break;
                case "-version":
                case "/version":
                    if (version == null)
                        version = new List<string>();
                    if (colonIndex >= 0)
                    {
                        int valueStartIndex = colonIndex + 1;
                        version.Add(args[i].Substring(valueStartIndex, args[i].Length - valueStartIndex));
                    }
                    else
                    {
                        i++;
                        if (i < args.Length)
                        {
                            version.Add(args[i]);
                        }
                        else
                        {
                            System.Console.WriteLine("Expected a version to be specified with the version parameter.");
                            return;
                        }
                    }
                    break;
                case "-?":
                case "/?":
                case "-help":
                case "/help":
                    showHelp = true;
                    break;
                default:
                    System.Console.WriteLine("Unrecognized parameter \"{0}\".", parameterName);
                    return;
            }
        }

        // At this point, all of the command line arguments have been read
        // and used to populate the variables that I defined at the top.
        // The rest of my application will work with the variables
        // and will not reference to args array again.
    }
Dr. Wily's Apprentice