views:

76

answers:

3

I'd like my console app to use hyphen-named inputs, like so:

myApp -S "myServerName" -D "myDatabaseName"

instead of the usual:

myApp "myServerName" "myDatabaseName"

I think the first is more friendly to developers that want to use my console app down the road. I think that I don't know what this type of input is called, else I woulda found it on google.

A: 

Put this in your arg-processing method:

    for (int i=0; i < args.Length; i++)
    {
        switch (args[i])
        {
            case "-f":  // string data
                i++;
                if (args.Length <= i) throw new ArgumentException(args[i]);
                _file = args[i];
                break;

            case "-p":  // boolean flag
                _pflag= true;
                break;

            case "-i":  // int argument, allows hex or decimal
                i++;
                if (args.Length <= i) throw new ArgumentException(args[i]);
                if (_intParam != DefaultIntParamValue)
                    throw new ArgumentException(args[i]);
                if (args[i].StartsWith("0x"))
                    _intParam = System.Int32.Parse(args[i].Substring(2), System.Globalization.NumberStyles.AllowHexSpecifier );
                else
                    _intParam = System.Int32.Parse(args[i]);
                break;


            case "-s":  // size, in bytes, K, MB, GB
                i++;
                if (args.Length <= i) throw new Exception(args[i-1]);
                if (args[i].ToUpper().EndsWith("K"))
                    _size = System.Int32.Parse(args[i].Substring(0,args[i].Length-1)) * 1024;
                else if (args[i].ToUpper().EndsWith("KB"))
                    _size = System.Int32.Parse(args[i].Substring(0,args[i].Length-2)) * 1024;
                else if (args[i].ToUpper().EndsWith("M"))
                    _size = System.Int32.Parse(args[i].Substring(0,args[i].Length-1)) * 1024*1024;
                else if (args[i].ToUpper().EndsWith("MB"))
                    _size = System.Int32.Parse(args[i].Substring(0,args[i].Length-2)) * 1024*1024;
                else
                    _size = Int32.Parse(args[i]);
                break;


            case "-?":
                throw new ArgumentException(args[i]);

            default:  // positional argument
                if (_positionalArg != null)
                    throw new ArgumentException(args[i]);

                _positionalArg = args[i];
                break;
        }
    }

I often put this into the constructor of a "runner" type.
This logic assumes the arg processing is done inside a try..catch, and in the catch, the Usage is displayed. Like this:

try 
{
    MyClass x = new MyClass(args);
    x.DoTheThing(); 
}
catch (Exception exc1)
{
   Usage(); 
}
Cheeso
+3  A: 

Everything that is entered after the executable name is called a command line argument.

But whether you use dashes or slashes or some other kind of keyword is completely up to the application to implement.

If you want to save yourself some effort, you might want to use an command line parser.

Here is an open source one that you can use. http://www.codeplex.com/cmdline

Mark Arnott
Or you can use http://commandline.codeplex.com/ (small bias as I've contributed to this project).
Agent_9191
I guess both of the first two answers work fine, but this one got the most upvotes.
jcollum
+1  A: 

I like using NDesk.Options. You just have to add that source file to your project. It's really easy to use and has good documentation. The code would look like:

string server = null;
string database = null;
var p = new OptionSet () {
    { "S",  v => server = v },
    { "D",  v => database = v },
   };
List<string> extra = p.Parse (args); // 'args' comes from Main (string [] args)
...

If you want automatic help to be generated, you would do:

string server = null;
string database = null;
var p = new OptionSet () {
    { "S", "Server name", v => server = v },
    { "D", "Database name", v => database = v },
    { "h", "Display help", v => { show_help = true; }},
   };
List<string> extra = p.Parse (args); // 'args' comes from Main (string [] args)
if (show_help) {
   Console.WriteLine ("Name of your program and brief description");
   p.WriteOptionDescriptions (Console.Out);
   Environment.Exit (0);
}
...
Gonzalo
Uhhh: "The NDesk.Options.dll assembly is currently UNSTABLE. Please provide any feedback on the API and design of the library. " (from the site you listed, front page)
jcollum
In this case, unstable means that the API might change, not that it does not work and since you can copy the single file to your project, API changes should not affect you.
Gonzalo