當需要用 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