The Sandbox Thread

7 posts

Forum Read Only

This forum has been made read only by the site admins. No new threads or comments can be added.

MSH-Style Command Line Parser for Console apps. V1.5

Back to Forum: The Sandbox
  • User profile image
    staceyw

    Quick and easy "MSH style" console input parameter parser with many features.  Super simple to use.  A single line of code will parse any amount of complicated parameters into the types you defined in the Data class. Also supports multiple Command "Sets". Will convert and verify the strings into the types defined in the public fields and/or properties of the attributed Data class.

    Example:
    --------
    //InArgs is the Data object defining the parameters.
    //args is from Main(string[] args).
    Parameters parms = Parameters.CreateParameters(new InArgs(), args);

    Summary of features:
    --------------------------
    - Supports named parameters and position parameters.
    - Parcial names.  "-Name" is same as "-n" or "-na".
    - Automaticly builds "Usage" and Detailed Help.
    - Supports all primitive types *and Arrays of those types.  Will also support any type that has a type converter to convert from a string.
    - Standardizes on "-" (not "/") for parm names.
    - Parameter/values can be delimited by colon or space.  Example: "-name xxx" or "-name:xxx"
    - Reserved parameters --, -?, -??, -h, -help, -ver, -version.
    - Mandatory parameters.
    - Prompt user with your prompt string if Mandatory parameter not given.

    A simple app with two optional parameters my look like:
    // InputArgsSimple.cs - Defines the expected parms, validations and help
    using System;
    using CmdParser;

    namespace MyConsoleApp
    {
     /// <summary>
     /// InputArgsSimple.cs
     /// Defines the parameters we expect at the command line.
     /// Here is a simple class that define two optional parameters.
     /// First is a bool named Flag and second is a string named Name.
     /// The command line to set these fields could be:
     /// MyCmd -Flag -Name John
     /// MyCmd -Fl:true -Nam:John
     /// MyCmd -n John -f:F
     ///
     /// Note: When using Named parameters, the order is not important.
     /// We can also seperate the parm name from the value using a space or ":".
     /// If a parameter is not given, the default value after construction is the
     /// value (i.e. not changed.)  Only need to supply enouph chars in parm names
     /// to disambiguate from other parms.
     /// </summary>
     [CmdHelp("Simple console app.", "This is a simple console app to demo CmdParser.", "www.mysite.com", "Copyright (c) 2005 MyOrg", null)]
     public class InputArgsSimple
     {
      [ParameterHelp("Starts app in windows mode.", "Start the program in windows mode.")]
      public bool W;

      [ParameterHelp("Name of user to find.", "The name of the user to find.")]
      public string Name;
      
      public InputArgsSimple()
      {
      }
     }
    }

    // Main console class.
    using System;
    using CmdParser;
    using System.Reflection;
    using System.Collections;

    namespace MyConsoleApp
    {
     class Class1
     {
      /// <summary>
      /// The main entry point for the application.
      /// </summary>
      [STAThread]
      static void Main(string[] args)
      {
       InputArgsSimple inArgs = new InputArgsSimple();
       try
       {
        Parameters parms = Parameters.CreateParameters(inArgs, args);

        if ( parms.IsHelpNeeded )
        {
         string helpString = "";
         switch(parms.HelpChars)
         {
          case "?":
           helpString = parms.GetUsageString(Assembly.GetExecutingAssembly());
           Console.WriteLine("\nUsage:");
           Console.WriteLine(helpString);
           Console.WriteLine("Note: For detailed help, use -??, -h, or -help.");
           break;
          case "h":
          case "help":
          case "??":
           helpString = parms.GetDetailedHelp(Assembly.GetExecutingAssembly());
           Console.WriteLine();
           Console.WriteLine(helpString);
           break;
         }
         return;
        }

        if ( parms.IsVersionNeeded )
        {
         Assembly assem = Assembly.GetExecutingAssembly();
         string ver = assem.GetName().Version.ToString();
         Console.WriteLine("Version: " + ver);
         return;
        }

        if ( parms.BeenSetCount == 0 )
        {
         // No parameters set at commandline, so display help.
         // This could mean something else to your program.
         string helpString = parms.GetUsageString(Assembly.GetExecutingAssembly());
         Console.WriteLine("\nUsage:");
         Console.WriteLine(helpString);
         Console.WriteLine("Note: For detailed help, use -??, -h, or -help.");
         return;
        }

        // Just testing, so show the parms we set.
        Console.WriteLine("\n\nParms:");
        ParameterSet pSet = parms.ActiveSet;
        foreach(Parameter p in pSet.Parameters)
        {
         string val = (p.Value == null) ? "Null" : p.Value.ToString();
         Console.WriteLine("{0}: {1}", p.Name, val);
        }
       }
       catch(Exception ex)
       {
        Console.WriteLine(ex.Message);
       }
      }
     }
    }

    As we defined some help, we can get automatic Usage and Help.  Usage looks like so:
    V:\MyConsoleApp\bin\Debug>myconsoleapp -?

    Usage:
    MyConsoleApp [-W boolean] [-Name string]

    Parameters:
    W         - Starts app in windows mode.
    Name      - Name of user to find.

    Note: For detailed help, use -??, -h, or -help.


    Detailed help would look like:
    V:\MyConsoleApp\bin\Debug>myconsoleapp -??

    MyConsoleApp Help
    ======================================================================
    Copyright (c) 2005 MyOrg
    Web Site: www.mysite.com
    Version : 1.0.1920.24820
    This is a simple console app to demo CmdParser.

    Parameters
    ----------------------------------------------------------------------
    -W
    [Boolean]
    [Mappings=(Default:-1)]
    Start the program in windows mode.

    -Name
    [String]
    [Mappings=(Default:-1)]

    Naturally, you could build your own help if required.
    Would really appreciate any feedback on issues, new features, likes/dislikes, etc.

    Version History
    -------------------
    1/9/2005 - v1.5 Updated to include SendMail sample client project using the CmdParser library.  Added CmdParser.Doc.


    --William Stacey[MVP]

  • User profile image
    databyte

    Not to complain... but there are about a hundred of these already.  The one I currently like that's simple, flexible, and lightweight is here:

    http://www.codeproject.com/csharp/command_line.asp

    I'm sure this is a lot of fun to build and a great learing exercise but codeproject.com has a few dozen more if that didn't do the job.

    Good luck with yours.

  • User profile image
    staceyw

    Thanks databyte.  But you will need to look closer.  This is nothing like those other parsers.  This is modeled after the MSH (i.e. Monad) parser.  Can handle all primitive types, arrays of those types, any other type you can define a converter for.  It also has integrated Detailed help and Usage help and a ton of validation such as:
    CmdHelp (Defines help for the whole command.)
    DefaultSet (Defines the default set when more sets match.)
    Parameter (base attribute)
    ParameterHelp (Defines help for the parm.)
    ParsingMandatoryParameter (Parm is required)
    ParsingParameterDeclaration
    ParsingParameterMapping (Maps parm to set name and position)
    ParsingPromptString (Prompt for input)
    ParsingVariableLengthParameterList (var list)
    SwitchParameter (a bool)
    ValidationCount (Array min/max count)
    ValidationLength (string min/max len)
    ValidationPattern (Regex pattern)
    ValidationRange (Object min/max range)
    ValidationSet (Set of strings that are valid.)

    You also get Parameter Sets, variable length parameter lists, Input Prompt, mandatory checks, various validations, etc.  In effect, allows you to Overload your command line parms into "Sets" and the engine figures out which set to use or throws proper error.  It also works with any combination of Named or Position parameters and figures out which set to use if possible.  You also get "Parcial" name support.  So "-n:hello" is the same as "-Name hello" or even "-na xyz" if we can disabiguate the name from other parms.  Other helpful things I need to write about.  Thanks.

  • User profile image
    Steven J Ackerman

    Excellent !

    Thank you for sharing.

    Steven J. Ackerman, Consultant
    ACS, Sarasota, FL
    http://www.acscontrol.com
    http://spaces.msn.com/members/sjackerman
     

  • User profile image
    Martin Kulov

    Hi William,

    It will be very helpfull to show some examples how to use it.

    Thanks,
    Martin

  • User profile image
    staceyw

    Added sample project (SendMail) using the lib.

  • User profile image
    stevenpack

    Great library William, definitely my favourite command line parser. Any chance you have any unit tests for it?

Conversation locked

This conversation has been locked by the site admins. No new comments can be made.