使用 PowerArgs 解析 Console / WinForm / WPF 的參數

當需要用 Console App / WinForm給其他應用程式呼叫時,比如工作排程,會需要分析調用端傳過來的參數。

PowserArgs 除了能分析參數並轉成強型別之外,還能生成詳細的說明文件,只需要定義幾個 Attribute 就能完成,真的是令我驚艷阿

我用兩個專案演示

Console Application .Net Fx 4.8 的專案,名為 Net48

Console Application .Net Core 3.1 的專案,名為 NetCore31

文章內容以 Net48 為主,範例都在 github 上

安裝套件

Install-Package PowerArgs
Install-Package Newtonsoft.Json

PowerArgs 官方連結:https://github.com/adamabdelhamed/PowerArgs

綁定模型

定義 Model

  • [ArgPosition(0)]:參數順序,可以不需要明確指定參數名稱。
  • [ArgShortcut("n")]:參數熱鍵。
  • [ArgDescription("Description of the argument")]:參數說明。
  • [ArgRequired(PromptIfMissing=bool)]:參數必填,若未填,會要求填寫
  • [ArgDefaultValue("SomeDefault")]:預設值,若參數未填,則使用
  • [ArgIgnore]:不綁定。
public class CopyFileRequest
{
    public static string MethodName = "Copy";

    [ArgRequired(PromptIfMissing = true)]
    [ArgDescription("來源路徑")]
    [ArgShortcut("-S")]
    [ArgPosition(1)]
    public string SourceFolder { get; set; }

    [ArgRequired(PromptIfMissing = true)]
    [ArgDescription("目標路徑")]
    [ArgPosition(2)]
    [ArgShortcut("-T")]
    public string DestinationFolder { get; set; }

    [ArgRequired(PromptIfMissing = true)]
    [ArgDescription("搜尋模式")]
    [ArgPosition(3)]
    [ArgShortcut("-SP")]
    public string SearchPattern { get; set; }
}

 

解析參數轉強型別

class Program
{
    static void Main(string[] args)
    {
       //解析參數
       var copyFileRequest = Args.Parse<CopyFileRequest>(args);
       Console.WriteLine($"解析參數 - {JsonConvert.SerializeObject(copyFileRequest)}");
    }
}

 

更詳細的 Attribute 可參考官方文件,https://github.com/adamabdelhamed/PowerArgs

 

調用時可使用兩種方式傳入參數,/ 和 -,如下

/SourceFolder:"D:\My Source" /DestinationFolder:"D:\My Target" /SearchPattern:*.iso

-SourceFolder "D:\My Source" -DestinationFolder "D:\My Target" -SearchPattern *.iso

熱鍵用法

/S:"D:\My Source" /T:"D:\My Destination" /SP:*.iso

-S "D:\My Source" -T "D:\My Destination" -SP *.iso

 

如何調試

介紹幾個我知道的方法

  • 用 VS IDE 偵錯時,在 Debug 視窗帶入參數
  • 測試專案呼叫 Main 方法 Args 陣列,注意存取修飾詞,可以用 internal + InternalsVisibleTo

@ AssemblyInfo.cs

[assembly: InternalsVisibleTo("組件名稱")]

@ Program.cs

internal class Program
{
    public static void Main(string[] args)
    {
       ....
    }
}

 

  • 用命令提示字元 / cmder.exe 調用,如下圖

解析參數,net48 /SourceFolder:"D:\My Source" /DestinationFolder:"D:\My Target" /SearchPattern:*.iso

 

拿到參數之後,就可以做你想要做的事。

 

綁定行為

除了解析參數轉成強型別之外,還可以綁定行為,我覺得這蠻酷的

綁定單一行為

  • Main 方法:只提供一個功能,注意,這裡是非靜態
  • [ArgExceptionBehavior(ArgExceptionPolicy.StandardExceptionHandling)]:捕捉綁定例外
  • [HelpHook]:提供說明

代碼如下:

[ArgExceptionBehavior(ArgExceptionPolicy.StandardExceptionHandling)]
public class SingleBehavior
{
    [HelpHook]
    [ArgShortcut("-?")]
    [ArgDescription("Shows this help")]
    public bool Help { get; set; }

    [ArgRequired(PromptIfMissing = true)]
    [ArgDescription("來源路徑")]
    [ArgShortcut("-S")]
    [ArgPosition(1)]
    public string SourceFolder { get; set; }

    [ArgRequired(PromptIfMissing = true)]
    [ArgDescription("目標路徑")]
    [ArgPosition(2)]
    [ArgShortcut("-D")]
    public string DestinationFolder { get; set; }

    [ArgRequired(PromptIfMissing = true)]
    [ArgDescription("搜尋模式")]
    [ArgPosition(3)]
    [ArgShortcut("-SP")]
    public string SearchPattern { get; set; }

    public void Main()
    {
        Console.WriteLine($"Main - {JsonConvert.SerializeObject(this)}");
    }
}

 

解析參數轉強型別並執行 Main 方法

class Program
{
    static void Main(string[] args)
    {
        Args.InvokeMain<SingleBehavior>(args);
    }
}

 

列出說明文件,net48 -?

 

呼叫 Main 方法,net48 /SourceFolder:"D:\My Source" /DestinationFolder:"D:\My Target" /SearchPattern:*.iso

 

綁定多個行為

只有一個行為不夠的話,還可以綁定多個行為,MultipleBehavior 有兩個方法,Copy、Delete,參數都不一樣

這裡多了一個特性可以用

  • [ArgExample("example text", "Example description")]:替行為加上範例
[ArgExceptionBehavior(ArgExceptionPolicy.StandardExceptionHandling)]
public class MultipleBehavior
{
    [HelpHook]
    [ArgShortcut("-?")]
    [ArgDescription("Shows this help")]
    public bool Help { get; set; }

    [ArgActionMethod]
    [ArgDescription("複製")]
    [ArgExample(@"NETApp Copy D:\Source D:\Target *.txt", "省略參數,需按照順序")]
    [ArgExample(@"NETApp Copy /SourceFolder:D:\Source /TargetFolder:D:\Target /SearchPattern:*.txt",
                "完整參數或是縮寫參數,不需要按照順序")]
    public void Copy(CopyFileRequest args)
    {
        Console.WriteLine($"Copy - {JsonConvert.SerializeObject(args)}");
    }

    [ArgActionMethod]
    [ArgDescription("刪除")]
    [ArgExample(@"NETApp Delete D:\Target *.txt", "省略參數,需按照順序")]
    [ArgExample(@"NETApp Delete /TargetFolder:D:\Target /SearchPattern:*.txt",
                "完整參數或是縮寫參數,不需要按照順序")]
    public void Delete(DeleteFileRequest args)
    {
        Console.WriteLine($"Copy - {JsonConvert.SerializeObject(args)}");
    }
}

 

public class DeleteFileRequest
{
    public static string MethodName = "Delete";

    [ArgRequired(PromptIfMissing = true)]
    [ArgDescription("目標路徑")]
    [ArgPosition(1)]
    [ArgShortcut("-D")]
    public string DestinationFolder { get; set; }

    [ArgRequired(PromptIfMissing = true)]
    [ArgDescription("搜尋模式")]
    [ArgPosition(2)]
    [ArgShortcut("-SP")]
    public string SearchPattern { get; set; }
}

 

解析參數並執行特定方法

class Program
{
    static void Main(string[] args)
    {
        Args.InvokeAction<MultipleBehavior>(args);
    }
}

 

列出所有方法的說明文件,net48 -?

 

列出 Copy 方法的說明文件,net48 copy -?

 

調用 Copy 方法,net48 copy /SourceFolder:"D:\My Source" /DestinationFolder:"D:\My Target" /SearchPattern:*.iso

 

調用 Delete 方法,net48 delete /SourceFolder:"D:\My Source" /DestinationFolder:"D:\My Target" /SearchPattern:*.iso

 

WinForm / WPF 專案如何接收 Args

WinForm

在 Main 方法新增 args

static class Program
{
    [STAThread]
    internal static void Main(string[] args)
    {
       ...
    }
}

 

WPF

我知道的有兩個方法可以取得 args,如下

public partial class App : Application
{
    public App()
    {
        var args = Environment.GetCommandLineArgs();
    }

    protected override void OnStartup(StartupEventArgs e)
    {
        var args = e.Args;
    }
}

 

專案位置

https://github.com/yaochangyu/sample.dotblog/tree/master/Args/Lab.ConsoleArgs

若有謬誤,煩請告知,新手發帖請多包涵


Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET

Image result for microsoft+mvp+logo