Buy Me a Coffee

Buy Me a Coffee!

Sunday, January 29, 2017

Follow up on Command Line Parser Library

In the last post I mentioned building command line tools with arguments and then using PowerShell provide a repeatable experience.  I think it is worth some additional time to talk through some additional options the Command Line Parser Library has and how to write a PowerShell script to read arguments from an XML file.

First, let look at some simple PowerShell code to call our command line tool.

[xml]$configurationDocument = Get-Content .\install.xml
If($configurationDocument.configuration.userName -ne '') 
    {$userName = $configurationDocument.configuration.userName}
If($configurationDocument.configuration.password -ne '') 
    {$password = $configurationDocument.configuration.password}

.\BlogPost -u $userName -p $password


The important part is the first line which reads the content of an XML file and makes it available within your script.  With the following XML:

<configuration>
    <userName>larrys@corp</userName>
    <password>mYP4$$w0rd!</password>
<!--
    <userName>otherName@domain</userName>
    <password>My0therP4ssw0rd!</password>
-->
</configuration>

I get the following results:

PS C:\blog> .\BlogPost.ps1
User Name: larrys@corp
Password (obscured): .........
No Default: False
Required: something hard coded
CommandLine.ParserSettings
Doing my work now.
PS C:\blog>

Next, the arguments I showed in the last post were strings and bools.  The bool had a default value, the strings did not, and neither were required.  This is the easiest type to use, and is the default behavior.  The library is very flexible though, and allows us to customize the behavior through settings. By changing from the Default parser to an instance we can pass a ParserSettings object into the constructor to alter the default behavior:


            var mySettings = new CommandLine.ParserSettings();
            mySettings.CaseSensitive = true;
            mySettings.HelpWriter = Console.Out;
            mySettings.IgnoreUnknownArguments = false;
            mySettings.MutuallyExclusive = true;
            mySettings.ParsingCulture = System.Globalization.CultureInfo.CurrentUICulture;
            var parser = new CommandLine.Parser(mySettings);
            var options = new Options();
            if (parser.ParseArgumentsStrict(args, options))
            {
If we examine the ParserSettings object, we can see that we can have case sensitive arguments (default is false), we can re-direct the output to a different stream, we can have it ignore unknown arguments, we can create sets of mutually exclusive arguments, and we can set the parsing culture.  With the settings above, I added the following options:



        [Option('r', "required", Required = true,
            HelpText = "This is a required parameter.")]
        public string Required { get; set; }
 
        [Option('t', "no default", 
            HelpText = "This is bool parameter with no default.")]
        public bool NoDefault { get; set; }
 
        [Option('a', Required = false, MutuallyExclusiveSet = "abc", 
            HelpText = "Choose A, B, or C")]
        public string ChoiceA { get; set; }
 
        [Option('b', Required = false, MutuallyExclusiveSet = "abc",
            HelpText = "Choose A, B, or C")]
        public string ChoiceB { get; set; }
 
        [Option('c', Required = false, MutuallyExclusiveSet = "abc",
            HelpText = "Choose A, B, or C")]
        public string ChoiceC { get; set; }

Which produce the following results:
C:\blog>BlogPost.exe -r bob
No Default: False
Required: bob
CommandLine.ParserSettings

Doing my work now.

C:\blog>BlogPost.exe -r bob -a something
No Default: False
Required: bob
Choice A: something
CommandLine.ParserSettings
Doing my work now.

C:\blog>BlogPost.exe -r bob -a something -c another
BlogPost 1.0.0.0
Copyright c Microsoft 2017

ERROR(S):
  -a option violates mutual exclusiveness.


  -v, --verbose       (Default: True) Prints all messages to standard output.

  -u, --userName      Username for a user with rights to create lists on the
                      destination site.

  -p, --password      Password for a user with rights to create lists on the
                      destination site.

  -r, --required      Required. This is a required parameter.

  -t, --no default    This is bool parameter with no default.

  -a                  Choose A, B, or C

  -b                  Choose A, B, or C

  -c                  Choose A, B, or C

  --help              Display this help screen.
In the next post on the Command Line Parser Library I will talk a bit about verbs.