Tuesday, October 18, 2011

Harnessing the PowerShell command line parser in .net

One of the annoying niggles about the .net framework is the lack of an intrinsic command line parser -- yes, there's Mono.Options or the F# power-pack, but they're not always just there to hand. PowerShell is there on Win7 and up, and is likely to be there on machines with older OS versions in a suitably technical environment, So if you just want to whip up a simple command line tool, and you're not writing it in PowerShell, why not at least borrow its features?

First, we want to get the argument list as provided -- for this we have to get the semi-raw line via Win32 (semi-raw as the shell will already have processed escapes -- in PowerShell that means that backticks, semi-colons and double-dashes are significant):

This uses the PowerShell tokenizer to strip out the executable name. We also want to be able to describe what the command line parameters are like, and other usage text

Then we can build a PowerShell function that takes the parameters we've defined, and just places them in a hash : this is the meat of the exercise

For producing a usage description, we can ask PowerShell for one, flatten it to a sequence of strings, and then strip out the unwanted PowerShell-isms

Finally, we can parse a supplied command-line, writing a failure reason and usage info if things fail

A simple example driver would be

There are some quirks -- Mandatory positional parameters and arbitrary nameless options don't mix : the current example program if given a command line "-Val hello -N 23 -S a b c" will yield

"$args" -> [|"a"; "b"; "c"|]
"ValueArg" -> "hello"
"SwitchArg" -> True
"NextArg" -> 23

Make NextArg mandatory, and instead it goes

A positional parameter cannot be found that accepts argument 'a'.


    This is the synopsis

    ConsoleApplication1.exe [[-ValueArg] <string>] [-NextArg] <int32> [-SwitchArg]...

So, perhaps not industrial strength; but suited to gentle use when there's nothing else to hand.

No comments :