概要
System.CommandLine ライブラリには、コマンドライン入力の解析やヘルプ テキストの表示など、コマンドライン アプリで一般的に必要とされる機能が用意されています。
System.CommandLineパッケージはプレリリース版なので、ご利用は計画的に。
やってみよう。
NuGet
基本
Program.cs
// ルートコマンドを設定
var root = new RootCommand("コマンド全体の説明");
// ルートコマンドの動作を設定
root.SetHandler(() => System.Console.WriteLine("実行されました。"));
// 実行
await root.InvokeAsync(args);
実行してみます。
> TestCommandLine
実行されました。
ヘルプを表示します。
> TestCommandLine --help
Description:
コマンド全体の説明
Usage:
TestCommandLine [options]
Options:
--version Show version information
-?, -h, --help Show help and usage information
バージョンを表示します。
> TestCommandLine --version
1.0.0
応用
Program.cs
// ルートコマンドを設定
var root = new RootCommand("コマンド全体の説明");
// グローバルオプションに--verboseオプション(値なし)を設定
var verboseOption = new Option<bool>("--verbose", "verboseオプションの説明");
verboseOption.AddAlias("-v");
verboseOption.Arity = ArgumentArity.Zero;
root.AddGlobalOption(verboseOption);
// コマンド1
var cmd1 = new Command("cmd1", "コマンド1の説明");
root.Add(cmd1);
// コマンド1の引数(省略可)
var cmd1arg1 = new Argument<string>("arg1", "コマンド1-引数1 の説明");
cmd1arg1.SetDefaultValue("arg1Value");
cmd1.AddArgument(cmd1arg1);
// コマンド1のオプション(省略可)
var cmd1op1 = new Option<string>("--op1", "コマンド1-オプション1 の説明");
cmd1op1.SetDefaultValue("op1Value");
cmd1.AddOption(cmd1op1);
// コマンド1の動作
cmd1.SetHandler((cmd1arg1Value, cmd1op1Value, verboseOptionValue) =>
{
Console.WriteLine($"cmd1 arg1 = {cmd1arg1Value} --op1 = {cmd1op1Value} --verbose = {verboseOptionValue}");
}, cmd1arg1, cmd1op1, verboseOption);
// コマンド2
var cmd2 = new Command("cmd2", "コマンド2の説明");
root.Add(cmd2);
// コマンド2の引数(必須)
var cmd2arg1 = new Argument<FileInfo>("arg1", "コマンド2-引数1 の説明");
cmd2.AddArgument(cmd2arg1);
// コマンド2の動作
cmd2.SetHandler((file, verboseOptionValue) =>
{
Console.WriteLine($"cmd2 arg1 = {file.FullName} --verbose = {verboseOptionValue}");
}, cmd2arg1, verboseOption);
// 実行
await root.InvokeAsync(args);
全体のヘルプ
> TestCommandLine --help
Description:
コマンド全体の説明
Usage:
TestCommandLine [command] [options]
Options:
-v, --verbose verboseオプションの説明
--version Show version information
-?, -h, --help Show help and usage information
Commands:
cmd1 <arg1> コマンド1の説明 [default: arg1Value]
cmd2 <arg1> コマンド2の説明
cmd1のヘルプ
> TestCommandLine cmd1 --help
Description:
コマンド1の説明
Usage:
TestCommandLine cmd1 [<arg1>] [options]
Arguments:
<arg1> コマンド1-引数1 の説明 [default: arg1Value]
Options:
--op1 <op1> コマンド1-オプション1 の説明 [default: op1Value]
-v, --verbose verboseオプションの説明
-?, -h, --help Show help and usage information
cmd1を実行 (引数・オプションなし)
> TestCommandLine cmd1
cmd1 arg1 = arg1Value --op1 = op1Value --verbose = False
cmd1を実行 (引数・オプションあり)
> TestCommandLine cmd1 abc --op1 def -v
cmd1 arg1 = abc --op1 = def --verbose = True
cmd2のヘルプ
> TestCommandLine cmd2 --help
Description:
コマンド2の説明
Usage:
TestCommandLine cmd2 <arg1> [options]
Arguments:
<arg1> コマンド2-引数1 の説明
Options:
-v, --verbose verboseオプションの説明
-?, -h, --help Show help and usage information
cmd2の実行(引数なし)
>TestCommandLine cmd2
Required argument missing for command: 'cmd2'.
cmd2の実行(引数あり)
C:\temp> TestCommandLine cmd2 hoge.txt
cmd2 arg1 = C:\temp\hoge.txt --verbose = False
終了コードを返したい
Program.cs
cmd2.SetHandler((file, verboseOptionValue) =>
{
bool result = true;
// ~省略~
//コマンドの戻り値
return Task.FromResult(result ? 0 : 1);
}, cmd2arg1, verboseOption);
// 実行
return await root.InvokeAsync(args);
解析だけしたい
Program.cs
// 実行
//await root.InvokeAsync(args);
var result = root.Parse(args);
if(result.Errors.Count > 0)
{
Console.WriteLine(result.Errors.Select(r => r.Message).Aggregate((r1, r2) => $"{r1}\r\n{r2}"));
}
else if (result.CommandResult.Command == cmd1)
{
Console.WriteLine(result.CommandResult.GetValueForArgument(cmd1arg1));
Console.WriteLine(result.CommandResult.GetValueForOption(cmd1op1));
Console.WriteLine(result.CommandResult.GetValueForOption(verboseOption));
}
else if (result.CommandResult.Command == cmd2)
{
Console.WriteLine(result.CommandResult.GetValueForArgument(cmd2arg1));
Console.WriteLine(result.CommandResult.GetValueForOption(verboseOption));
}
DI
タブ補完