Command-line argument parser

This post has been in my Drafts folder for quite some time. Read on if you are interested in command-line argument/parameter parsing.


I’ve blogged a couple of times on the Ventrilo (now on version 3.0) proxy and status port that Divinity and myself wrote. The console application that works both as a proxy and a status requistor takes quite a number of command-line arguments. I wanted to get these arguments working:

























































Argument Type Description Short form Required
/Server string DNS or IP Address of Ventrilo server /s Yes
/Port int Port of Ventrilo server /p Yes
/StatusPassword string Password for status requests /sp No
/AdminPassword string Password for admin status /ap No
/LogonPassword string Password for server logon /lp No
/ClientProxyPort int Local port for client-side proxy /l No
/ServerProxyPort int Remote port for server-side proxy /r No
/Command Status/ClientProxy Command to execute /c Yes

For such a list (yours might be similar or even larger) you can imagine this can be quite a lot of code to get this working. I stumbled upon a C# implementation for command-line argument parsing by Peter Hallam, formerly Microsoft, who had a blog back then. The source code is available from GotDotNet, which is destined to be shut down. Get it while you can (or from the attachment on this post).


You need to do some preparations on declaring the arguments that you want, but after that the parsing itself reduces to the following:



public static void Main(string[] args)


{


  VentriloUtilArguments parsedArguments = new VentriloUtilArguments();


  if (Parser.ParseArgumentsWithUsage(args, parsedArguments))


  {


    Program app = new Program();


    app.ExecuteCommand(parsedArguments);


  }


}


The important part is highlighted in bold. I’ve created a VentriloArguments class, which I’ll describe in a moment. For now, suffice to say that these hold all argument values for the parameters as listed in the table above. Peter’s work surfaces as the Parser class. The call to Parser.ParseArgumentsWithUsage will do the heavy lifting. You pass both the real arguments from the console application and the container for the parsed arguments. The container should be a reference type (i.e. class), so it can be filled with the parsed values by the parser.


Here’s part of the VentriloArguments class.



  public class VentriloUtilArguments


  {


    private IPEndPoint serverEndPoint = null;


    [Argument(ArgumentType.Required, HelpText=“DNS or IP Address of Ventrilo server”,


        LongName=“Server”, ShortName=“s”)]


    public string ServerAddress;


    [Argument(ArgumentType.Required, HelpText=“Port of Ventrilo server”, ShortName=“p”)]


    public int Port;


    [Argument(ArgumentType.AtMostOnce, HelpText = “Password for status requests”, ShortName=“sp”)]


    public string StatusPassword;


It is a simple System.Object derived class that has public fields for each command-line parameter. The type of the field determines the type of the parameter, the field name corresponds (by default) to the parameter name. Each field that must serve as a parameter has been decorated with the ArgumentAttribute. The constructor arguments of the attribute set all the properties as specified above. The first one specifies whether the parameter is required, can be used at most once or multiple times (and should be unique if so). You can also mark one argument as DefaultArgument so you do not have to name the argument. And that’s about it. No other work needed in most cases.


You’ll get a lot for free from Peter’s implementation. First of all, all parsing will be taken care of. There’s also a sanity check for required arguments. If anything is wrong, it is reported so. You can also get an usage summary by running the /? option.


CommandLineArguments 


Additional arguments can be read from a response file.


I found it useful to declare a property to change the type for a parameter. In particular I used a property of type System.Net.IPAddress to change a string address (either DNS or IPv4) into an IPAddress.


So, there you go. Check out Peter Hallam’s implementation if you need to create a program that has command-line arguments. It will save you a lot of work.


BTW, if you are curious to find out what Peter Hallam looks like, check out this video on automatic properties.
BTW2, the Ventrilo work will be continued this Friday when Divinity and myself will do another Freaky Twelve Hours session.

Advertisements
This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s