The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

介紹好用元件:ConsoleFx ( 處理命令列程式的函示庫 )

我之前寫 Console Program 時都是自己分析執行時輸入的參數,程式碼寫的也很醜,也很難 reuse,導致每次開發 Console Program 的程式碼都不太一致,有時後為了方便起見就亂寫一通,等累積多了之後就變的不好維護了。

最近在 CodePlex 發現了一個 ConsoleFx 專案,提供一套很方便的開發架構,他把一些在 Console 模式下開發 .NET 程式會處理的程式碼都寫好了,尤其是對參數、例外狀況、輸入資料格式驗證等常見的程式尤其方便,不但省去了許多開發時間,也提供了一致的開發架構,程式碼也會比較容易維護。

一般來說,若有用過指令列工具時,通常只要在指令後面加上 /? 就會出現使用說明,例如:

CLEAN [-dir:<directory mask>] [-file:<file mask>] [-norecurse] <base directory> 

當使用 ConsoleFx 時會用到一些專有名詞需先解說一下,這也是一般在寫 Console Program 時都應該到的東西:

  1. Switch
    • 如以上範例的 -dir-norecurse 就是所謂的 Switch。
    • 通常以減號(–)或以斜線(/)開頭。
    • 通常使用 Switch 的目的在於設定 Console Program 執行時的選項。
  2. Switch Parameters
    • 如以上範例的 <directory mask> 或 <file mask> 就是該 Switch 的參數。
  3. Parameters
    • 如以上範例的 <base directory> 就是該程式的主要參數。
    • 主要參數前面沒有接著 Switch,而是獨立存在的參數。

ConsoleFx 1.0 提供的功能與特色有

  • 輸入的參數可透過 Attribute 宣告與 Property 搭配使用
    • 將輸入的參數轉成屬性(Property)好處是可以在程式中可直接存取輸入參數,無須在讀取 params[] 字串陣列。
  • 可限制 switch 與 parameter 參數輸入的順序、格式、與參數出現的次數
    • 所有的設定都是透過 Attributes 宣告完成。
  • 輸入參數驗證(Switch validation)
    • 可透過設定屬性(Attribute)的方式設定 switch 的參數是否符合定義。
    • 目前可驗證的資料類型有:
      • Boolean
        • 驗證輸入參數是否為 Boolean 格式 ( True/False )
      • Integer
        • 可驗證輸入是否為數字
      • Lookup
        • 可提供一組字串清單,用逗號( , )分隔,用以驗證輸入的參數是否符合格式
          [LookupValidator(ParameterIndex.FirstParameter, "SHA1,MD5")]
      • Enum
        • 功能雷同於 Lookup 驗證類別,差別在於改以 Enum 型別定義可輸入的字串
        • 可指定一個 Enum 型別,讓輸入的參數必須符合 Enum 中定義的名稱
      • Path
        • 檢查輸入的參數是否回有效路徑
        • 也可檢查檔案、目錄是否存在
      • Regex
        • 可自訂 Regex 樣式比對輸入的字串
      • String
        • 可限定輸入字串的長度
    • 驗證的類型你還可以透過繼承 BaseValidatorAttribute 來擴充。
  • 錯誤處理(Error handling)
    • 當程式執行發生例外狀況(Exceptions),預設的錯誤訊息都集中在 ConsoleFx.CommandLineException.Message 類別中,你可以直接修改這個類別中的常數自訂顯示的錯誤訊息。
    • 另外你也可以在 Validator 類別中自訂當驗證失敗後的錯誤訊息。
  • 簡化常見的使用情境(Simplify common usage scenarios)
    • 只要繼承 ConsoleFx.ConsoleProgram 基底類別,就僅需覆寫(override)以下 2 個方法程式就會自動接受 /h 或 -h 參數(switch),若有加上 -h 就會自動執行 DisplayUsage() 方法,否則就會自動進入 ExecuteNormal() 方法執行:
      • public override void DisplayUsage()
      • public override int ExecuteNormal(string[] parameters)

目前來說 ConsoleFx Command Line Processing Library 線上所提供的文件並不多,但有點經驗的 .NET 開發人員應該很容易就可以從 Sample Code 中看懂他的使用方法。

最後分享一些使用心得

  • 初始 ConsoleFX 專案的基本流程如下:
    1. 新增 Console Application 專案
    2. 加入 ConsoleFX 參考
    3. 修改 Program.cs 的內容,範本如下:
      using ConsoleFx;
      using ConsoleFx.Validators;
      
      namespace ConsoleApplication1
      {
          [CommandLine(Grouping=CommandLineGrouping.DoesNotMatter)]
          class Program : ConsoleProgram
          {
              public static int Main(string[] args)
              {
                  return CommandLine.Run<Program>(args);
              }
      
              public override void DisplayUsage()
              {
                  ConsoleEx.WriteLine("ConsoleApplication1.exe [/SwitchA:<switch_parameter>] [<param1>] [...]");
              }
      
              string _switch_a;
      
              [Switch("SwitchA", ShortName = "a", MaxOccurences = 1, CaseSensitive = false, Order = 1)]
              [SwitchUsage(ProgramMode.Help, SwitchUsage.NotAllowed)]
              [SwitchUsage(ProgramMode.Normal, SwitchUsage.Optional)]
              [StringValidator(ParameterIndex.FirstParameter, MinLength = 1, MaxLength = 10)]
              public void SwitchA(string[] parameters)
              {
                  if (parameters.Length > 0)
                  {
                      _switch_a = parameters[0];
                  }
              }
      
              public override int ExecuteNormal(string[] parameters)
              {
                  return 0;
              }
          }
      }
      注意:ConsoleFX 中的 Main 回傳值是 int 喔。
  • 所有的 switch 選項參數要套用必須用公開方法(public method)實做。
    [Switch("algorithm", ShortName = "a", MinParameters = 0, MaxParameters = 1)]
    [SwitchUsage(ProgramMode.Help, SwitchUsage.NotAllowed)]
    [SwitchUsage(ProgramMode.Normal, SwitchUsage.Optional)]
    [LookupValidator(ParameterIndex.FirstParameter, "SHA1,MD5,SHA256,SHA384,SHA512")]
    public void AlgorithmSwitch(string[] parameters)
    {
        if (parameters.Length > 0)
            _algorithm = parameters[0];
    }
  • Parameters 一般參數可套用在公開屬性(public property)上,以強型別的方式運作。
    [ParameterProperty(ProgramMode.Normal, 1)]
    [PathValidator(ProgramMode.Normal, PathType=PathType.Folder, CheckIfExists=true)]
    [StringValidator(ParameterIndex.FirstParameter, MinLength = 1, MaxLength = 100)]
    public string Path
    {
        get {
            return _path;
        }
        set {
            _path = value;
        }
    }
  • ExecuteNormal() 若正常執行回傳值應為 0,若有錯誤發生應回應非 0 的值。
  • ExecuteNormal(string[] parameters) 傳入的 Parameters 不會有 switch 的任何參數。
  • 如果你有部分參數 Binding 到 Property 中,這些參數還是會以 string 的型態傳到 ExecuteNormal() 中。
  • ConsoleFX 專案有兩種執行模式(ProgramMode):
    • ProgramMode.Normal
      • 正常執行 Console Application 的情況。
    • ProgramMode.Help
      • 進入/顯示 Help 選單時的模式。
  • ConsoleFX 專案的執行模式(ProgramMode)可自訂擴充,例如你若要從 Console Application 啟動 Windows Form 的程式時,可以自訂一個 Mode 叫做 ProgramMode.Windows 。

相關連結