Jump to content
Xtreme .Net Talk

Recommended Posts

Posted

I've parsed the command line on a console app a couple of different ways but I'm curious if there is a pattern or "best" way to do it. Physically parsing is easy. I've got a C# implementation of the GetOpt library. It's applying the arguments to the business logic -- setting up the application to run. That is the part I wonder about.

 

Here is what I generally do:

Public Class CommandLineApp

   //define these up top so it's easier to change them later
   Private Class DefinedParameters  
       Public Const firstArgLong As String = "arg1"
       //...
   End Class

   Public Sub New()

   End Sub

   Public CommandLinePattern()
      //1. Get the command line parameters -- either passed in or Environment.GetCommandLineArgs()

      //2. Check initial error Conditions for early trouble

      //3. Set up GetOpt

      Try
             //4. Parse command line using GetOpt
         
             //5. Check for early termination scenarios -- user asks for help or version number, improper use of arguments, etc.

             //6. Set up boolean flags or variables for all the parameters that are left that could be good (such as hide banner or output file or configuration type)

             //7. Run the business/meaty part of the app with the flags/variables

      Catch e As ArgumentException
             Console.WriteLine(e.Message)
             ShowHelp()
      End Try
End Function

 

Here's an example in code to perhaps make things a little more clear. You can ignore this if you want, I'm just including it as an example to supplement some of my statements above.

Public Class CommandLineApp

   ''define these up top so it's easier to change them later
   Private Class DefinedParameters  
       Public Const loud As String = "loud"
       Public Const loud2 As String = "l"
       Public Const hidebanner As String = "hidebanner"
       Public Const hidebanner2 As String = "b"
       Public Const version As String = "version"
       Public Const version2 As String = "v"
       Public Const help As String = "help"
       Public Const help2 As String = "h"
       Public Const help3 As String = "?"
   End Class
'
   Public Sub New()
'
   End Sub
'
   'Usage: Appy filename [-l|--loud] [-b|--hidebanner] | [-v|--version] | [--help|-h|-?]
   ''This is called from the static Main() function but could easily BE the Main()
   Public Function Run(ByVal commandLineArgs As String()) As Boolean

       If commandLineArgs.Length = 1 Then  ''you have to either a filename, -v, or -h or the user needs more help
           ShowHelp()
           Return True
       End If

       ''Setting up GetOpt
       Dim commandLineParser As New Heyes.GetOpt(commandLineArgs)

       Dim expectedArgs() As String = {DefinedParameters.loud, DefinedParameters.loud2, _
                                       DefinedParameters.hidebanner, DefinedParameters.hidebanner2, _
                                       DefinedParameters.version, DefinedParameters.version2, _
                                       DefinedParameters.help, DefinedParameters.help2, DefinedParameters.help3}

       Try
           commandLineParser.SetOpts(expectedArgs)
           commandLineParser.Parse()

           ''If there is a request for the version, always honor it
           If commandLineParser.IsDefined(DefinedParameters.version) OrElse commandLineParser.IsDefined(DefinedParameters.version2) Then
               ShowBanner()
               Return True
           End If

           ''if more than one file is attempted, send the user some help
           If commandLineParser.Args.Count > 2 Then ''1 or 0 files is alright.  Remember, the exe is the first arg
               Console.WriteLine("Only one file may be specified at a time.")
               ShowHelp()
               Return True 'ditch out, becuase you failed
           End If

           ''no matter what, if the user wants help, give it to them, unless they want the version which I took care of above and ditched out
           If commandLineParser.IsDefined(DefinedParameters.help) OrElse _
              commandLineParser.IsDefined(DefinedParameters.help2) OrElse _
              commandLineParser.IsDefined(DefinedParameters.help3) Then

               ShowHelp()
               Return True ''ditch out, we gave them their help.
           End If

           If commandLineParser.IsDefined(DefinedParameters.loud) AndAlso commandLineParser.IsDefined(DefinedParameters.loud2) Then
               Console.WriteLine("Options cannot be specified more than once")
               Console.WriteLine("Paramater name: " + DefinedParameters.loud + ", " + DefinedParameters.loud2)
               ShowHelp()
               Return True
           End If

           If commandLineParser.IsDefined(DefinedParameters.hidebanner) AndAlso commandLineParser.IsDefined(DefinedParameters.hidebanner2) Then
               Console.WriteLine("Options cannot be specified more than once")
               Console.WriteLine("Paramater name: " + DefinedParameters.hidebanner + ", " + DefinedParameters.hidebanner2)
               ShowHelp()
               Return True
           End If

           ''define the arguments we have that aren't a help or version
           Dim hideBanner As Boolean = False

           If commandLineParser.IsDefined(DefinedParameters.loud) OrElse commandLineParser.IsDefined(DefinedParameters.loud2) Then
               Me._loud = True
           End If

           If commandLineParser.IsDefined(DefinedParameters.hidebanner) OrElse commandLineParser.IsDefined(DefinedParameters.hidebanner2) Then
               hideBanner = True
           End If

           ''Now down to business
           Execute(commandLineParser.Args(1), hideBanner)
           Return True

       Catch e As ArgumentException
           Console.WriteLine(e.Message)
           ShowHelp()
           Return True
       End Try
End Function

 

What do you do? Is there a good pattern to use or any general concepts that work particularly well? As I've said, what I do works, it just feels kind of clunky. I'm just curious what other developers are doing with regards to command line interfaces.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...