Öğretici: Kullanmaya başlama System.CommandLine
Önemli
System.CommandLine
şu anda ÖNİzLEME aşamasındadır ve bu belgeler 2.0 beta 4 sürümüne yöneliktir.
Bazı bilgiler, yayımlanmadan önce önemli ölçüde değiştirilebilen yayın öncesi ürünle ilgilidir. Burada verilen bilgilerle ilgili olarak Microsoft açık veya zımni hiçbir garanti vermez.
Bu öğreticide kitaplığı kullanan bir .NET komut satırı uygulamasının nasıl oluşturulacağı gösterilmektedirSystem.CommandLine
. Tek bir seçeneği olan basit bir kök komutu oluşturarak başlayacaksınız. Ardından bu tabana ekleyeceksiniz ve her komut için birden çok alt komut ve farklı seçenekler içeren daha karmaşık bir uygulama oluşturacaksınız.
Bu öğreticide şunların nasıl yapıldığını öğreneceksiniz:
- Komutlar, seçenekler ve bağımsız değişkenler oluşturun.
- Seçenekler için varsayılan değerleri belirtin.
- Komutlara seçenekler ve bağımsız değişkenler atayın.
- Bir komut altındaki tüm alt komutlara yinelemeli olarak bir seçenek atayın.
- Birden çok iç içe alt komut düzeyiyle çalışma.
- Komutlar ve seçenekler için diğer adlar oluşturun.
- , ,
string[]
,int
,bool
FileInfo
ve sabit listesi seçenek türleriylestring
çalışın. - Seçenek değerlerini komut işleyici koduna bağlayın.
- Seçenekleri ayrıştırma ve doğrulama için özel kod kullanın.
Önkoşullar
- C# uzantısına sahip Visual Studio Code gibi bir kod düzenleyicisi.
- .NET 6 SDK'sı.
Veya
- .NET masaüstü geliştirme iş yükü yüklü Visual Studio 2022.
Uygulama oluşturma
"scl" adlı bir .NET 6 konsol uygulaması projesi oluşturun.
Proje için scl adlı bir klasör oluşturun ve ardından yeni klasörde bir komut istemi açın.
Şu komutu çalıştırın:
dotnet new console --framework net6.0
System.CommandLine paketini yükleyin
Şu komutu çalıştırın:
dotnet add package System.CommandLine --prerelease
--prerelease
Kitaplık hala beta sürümünde olduğundan bu seçenek gereklidir.
Program.cs dosyasının içeriğini aşağıdaki kodla değiştirin:
using System.CommandLine; namespace scl; class Program { static async Task<int> Main(string[] args) { var fileOption = new Option<FileInfo?>( name: "--file", description: "The file to read and display on the console."); var rootCommand = new RootCommand("Sample app for System.CommandLine"); rootCommand.AddOption(fileOption); rootCommand.SetHandler((file) => { ReadFile(file!); }, fileOption); return await rootCommand.InvokeAsync(args); } static void ReadFile(FileInfo file) { File.ReadLines(file.FullName).ToList() .ForEach(line => Console.WriteLine(line)); } }
Yukarıdaki kod:
türünde FileInfo adlı
--file
bir seçenek oluşturur ve bunu kök komutuna atar:var fileOption = new Option<FileInfo?>( name: "--file", description: "The file to read and display on the console."); var rootCommand = new RootCommand("Sample app for System.CommandLine"); rootCommand.AddOption(fileOption);
ReadFile
Kök komut çağrıldığında çağrılacak yöntemin bu olduğunu belirtir:rootCommand.SetHandler((file) => { ReadFile(file!); }, fileOption);
Kök komut çağrıldığında belirtilen dosyanın içeriğini görüntüler:
static void ReadFile(FileInfo file) { File.ReadLines(file.FullName).ToList() .ForEach(line => Console.WriteLine(line)); }
Uygulamayı test etme
Komut satırı uygulaması geliştirirken test etmek için aşağıdaki yollardan herhangi birini kullanabilirsiniz:
dotnet build
Komutunu çalıştırın ve yürütülebilir dosyayı çalıştırmak için scl/bin/Debug/net6.0 klasöründe bir komut istemi açın:dotnet build cd bin/Debug/net6.0 scl --file scl.runtimeconfig.json
Aşağıdaki örnekte olduğu gibi, sonrasına ekleyerek
--
seçenek değerlerini komutu yerinerun
uygulamaya geçirindotnet run
:dotnet run -- --file scl.runtimeconfig.json
.NET 7.0.100 SDK Önizlemesi'nde komutunu
dotnet run --launch-profile <profilename>
çalıştırarak launchSettings.json dosyasını kullanabilirsinizcommandLineArgs
.Projeyi bir klasörde yayımlayın, bu klasörde bir komut istemi açın ve yürütülebilir dosyayı çalıştırın:
dotnet publish -o publish cd ./publish scl --file scl.runtimeconfig.json
Visual Studio 2022'demenüden Hata Ayıklama Özelliklerinde Hata Ayıklama'yı> seçin ve Komut satırı bağımsız değişkenleri kutusuna seçenekleri ve bağımsız değişkenleri girin. Örneğin:
Ardından, örneğin Ctrl+F5 tuşlarına basarak uygulamayı çalıştırın.
Bu öğreticide, bu seçeneklerden ilkini kullandığınız varsayılır.
Uygulamayı çalıştırdığınızda, seçeneği tarafından --file
belirtilen dosyanın içeriği görüntülenir.
{
"runtimeOptions": {
"tfm": "net6.0",
"framework": {
"name": "Microsoft.NETCore.App",
"version": "6.0.0"
}
}
}
Yardım çıkışı
System.CommandLine
otomatik olarak yardım çıkışı sağlar:
scl --help
Description:
Sample app for System.CommandLine
Usage:
scl [options]
Options:
--file <file> The file to read and display on the console.
--version Show version information
-?, -h, --help Show help and usage information
Sürüm çıkışı
System.CommandLine
otomatik olarak sürüm çıkışı sağlar:
scl --version
1.0.0
Alt komut ve seçenekler ekleme
Bu bölümde şunları yapacaksınız:
- Daha fazla seçenek oluşturun.
- Bir alt komut oluşturun.
- Yeni seçenekleri yeni alt komutlara atayın.
Yeni seçenekler ön plan ve arka plan metin renklerini ve okuma hızını yapılandırmanıza olanak sağlar. Bu özellikler , Teleprompter konsol uygulaması öğreticisinden gelen bir alıntı koleksiyonunu okumak için kullanılacaktır.
Bu örneğin GitHub deposundakisampleQuotes.txtdosyasını proje dizininize kopyalayın. Dosyaları indirme hakkında bilgi için Örnekler ve Öğreticiler'deki yönergelere bakın.
Proje dosyasını açın ve kapanış
</Project>
etiketinden hemen önce bir<ItemGroup>
öğe ekleyin:<ItemGroup> <Content Include="sampleQuotes.txt"> <CopyToOutputDirectory>Always</CopyToOutputDirectory> </Content> </ItemGroup>
Bu işaretlemenin eklenmesi, uygulamayı oluştururken metin dosyasının bin/debug/net6.0 klasörüne kopyalanmasına neden olur. Bu nedenle yürütülebilir dosyayı bu klasörde çalıştırdığınızda, klasör yolu belirtmeden dosyaya ada göre erişebilirsiniz.
Program.cs dosyasında, seçeneği oluşturan koddan
--file
sonra, okuma hızını ve metin renklerini denetlemek için seçenekler oluşturun:var delayOption = new Option<int>( name: "--delay", description: "Delay between lines, specified as milliseconds per character in a line.", getDefaultValue: () => 42); var fgcolorOption = new Option<ConsoleColor>( name: "--fgcolor", description: "Foreground color of text displayed on the console.", getDefaultValue: () => ConsoleColor.White); var lightModeOption = new Option<bool>( name: "--light-mode", description: "Background color of text displayed on the console: default is black, light mode is white.");
Kök komutu oluşturan satırdan sonra, seçeneği ekleyen
--file
satırı silin. Burada kaldırıyorsunuz çünkü yeni bir alt komut ekleyeceksiniz.var rootCommand = new RootCommand("Sample app for System.CommandLine"); //rootCommand.AddOption(fileOption);
Kök komutu oluşturan satırdan sonra bir
read
alt komut oluşturun. Bu alt komuta seçenekleri ekleyin ve alt komutu kök komutuna ekleyin.var readCommand = new Command("read", "Read and display the file.") { fileOption, delayOption, fgcolorOption, lightModeOption }; rootCommand.AddCommand(readCommand);
SetHandler
Kodu yeni alt komut için aşağıdakiSetHandler
kodla değiştirin:readCommand.SetHandler(async (file, delay, fgcolor, lightMode) => { await ReadFile(file!, delay, fgcolor, lightMode); }, fileOption, delayOption, fgcolorOption, lightModeOption);
Kök komutunun artık bir işleyiciye ihtiyacı olmadığından artık kök komutunda çağrıda
SetHandler
bulunmuyorsunuz. Bir komutun alt komutları olduğunda, genellikle bir komut satırı uygulaması çağrılırken alt komutlardan birini belirtmeniz gerekir.ReadFile
işleyici yöntemini aşağıdaki kodla değiştirin:internal static async Task ReadFile( FileInfo file, int delay, ConsoleColor fgColor, bool lightMode) { Console.BackgroundColor = lightMode ? ConsoleColor.White : ConsoleColor.Black; Console.ForegroundColor = fgColor; List<string> lines = File.ReadLines(file.FullName).ToList(); foreach (string line in lines) { Console.WriteLine(line); await Task.Delay(delay * line.Length); }; }
Uygulama şimdi şöyle görünür:
using System.CommandLine;
namespace scl;
class Program
{
static async Task<int> Main(string[] args)
{
var fileOption = new Option<FileInfo?>(
name: "--file",
description: "The file to read and display on the console.");
var delayOption = new Option<int>(
name: "--delay",
description: "Delay between lines, specified as milliseconds per character in a line.",
getDefaultValue: () => 42);
var fgcolorOption = new Option<ConsoleColor>(
name: "--fgcolor",
description: "Foreground color of text displayed on the console.",
getDefaultValue: () => ConsoleColor.White);
var lightModeOption = new Option<bool>(
name: "--light-mode",
description: "Background color of text displayed on the console: default is black, light mode is white.");
var rootCommand = new RootCommand("Sample app for System.CommandLine");
//rootCommand.AddOption(fileOption);
var readCommand = new Command("read", "Read and display the file.")
{
fileOption,
delayOption,
fgcolorOption,
lightModeOption
};
rootCommand.AddCommand(readCommand);
readCommand.SetHandler(async (file, delay, fgcolor, lightMode) =>
{
await ReadFile(file!, delay, fgcolor, lightMode);
},
fileOption, delayOption, fgcolorOption, lightModeOption);
return rootCommand.InvokeAsync(args).Result;
}
internal static async Task ReadFile(
FileInfo file, int delay, ConsoleColor fgColor, bool lightMode)
{
Console.BackgroundColor = lightMode ? ConsoleColor.White : ConsoleColor.Black;
Console.ForegroundColor = fgColor;
List<string> lines = File.ReadLines(file.FullName).ToList();
foreach (string line in lines)
{
Console.WriteLine(line);
await Task.Delay(delay * line.Length);
};
}
}
Yeni alt komutu test etme
Şimdi alt komutu belirtmeden uygulamayı çalıştırmayı denerseniz, bir hata iletisi alırsınız ve ardından kullanılabilir alt komutu belirten bir yardım iletisi alırsınız.
scl --file sampleQuotes.txt
'--file' was not matched. Did you mean one of the following?
--help
Required command was not provided.
Unrecognized command or argument '--file'.
Unrecognized command or argument 'sampleQuotes.txt'.
Description:
Sample app for System.CommandLine
Usage:
scl [command] [options]
Options:
--version Show version information
-?, -h, --help Show help and usage information
Commands:
read Read and display the file.
Alt komutun read
yardım metni dört seçeneğin kullanılabilir olduğunu gösterir. Sabit listesi için geçerli değerleri gösterir.
scl read -h
Description:
Read and display the file.
Usage:
scl read [options]
Options:
--file <file> The file to read and display on the console.
--delay <delay> Delay between lines, specified as milliseconds per
character in a line. [default: 42]
--fgcolor Foreground color of text displayed on the console.
<Black|Blue|Cyan|DarkBlue|DarkCyan|DarkGray|DarkGreen|Dark [default: White]
Magenta|DarkRed|DarkYellow|Gray|Green|Magenta|Red|White|Ye
llow>
--light-mode Background color of text displayed on the console:
default is black, light mode is white.
-?, -h, --help Show help and usage information
Yalnızca --file
seçeneği belirterek alt komutu read
çalıştırın ve diğer üç seçenek için varsayılan değerleri alırsınız.
scl read --file sampleQuotes.txt
Karakter başına 42 milisaniye varsayılan gecikme, okuma hızının yavaşlamasına neden olur. Daha düşük bir sayıya ayarlayarak --delay
hızlandırabilirsiniz.
scl read --file sampleQuotes.txt --delay 0
metin renklerini ayarlamak için ve --light-mode
kullanabilirsiniz--fgcolor
:
scl read --file sampleQuotes.txt --fgcolor red --light-mode
için --delay
geçersiz bir değer sağlayın ve hata iletisi alırsınız:
scl read --file sampleQuotes.txt --delay forty-two
Cannot parse argument 'forty-two' for option '--int' as expected type 'System.Int32'.
için --file
geçersiz bir değer sağlayın ve özel durum alırsınız:
scl read --file nofile
Unhandled exception: System.IO.FileNotFoundException:
Could not find file 'C:\bin\Debug\net6.0\nofile'.
Alt komutlar ve özel doğrulama ekleme
Bu bölüm, uygulamanın son sürümünü oluşturur. Tamamlandığında, uygulamada aşağıdaki komutlar ve seçenekler bulunur:
- adlı genel* seçeneğiyle root komutu
--file
quotes
komuturead
,--fgcolor
ve adlı seçeneklerin yer aldığı--delay
komut--light-mode
add
ve adlıquote
bağımsız değişkenleri içeren komutbyline
delete
komutu ve adlandırılmış seçenek--search-terms
* Genel bir seçenek, atandığı komutta kullanılabilir ve tüm alt komutları için yinelemeli olarak kullanılabilir.
Kullanılabilir komutların her birini seçenekleri ve bağımsız değişkenleriyle çağıran örnek komut satırı girişi aşağıda verilmiştir:
scl quotes read --file sampleQuotes.txt --delay 40 --fgcolor red --light-mode
scl quotes add "Hello world!" "Nancy Davolio"
scl quotes delete --search-terms David "You can do" Antoine "Perfection is achieved"
Program.cs dosyasında, seçeneğini oluşturan
--file
kodu aşağıdaki kodla değiştirin:var fileOption = new Option<FileInfo?>( name: "--file", description: "An option whose argument is parsed as a FileInfo", isDefault: true, parseArgument: result => { if (result.Tokens.Count == 0) { return new FileInfo("sampleQuotes.txt"); } string? filePath = result.Tokens.Single().Value; if (!File.Exists(filePath)) { result.ErrorMessage = "File does not exist"; return null; } else { return new FileInfo(filePath); } });
Bu kod, özel ayrıştırma, doğrulama ve hata işleme sağlamak için kullanır ParseArgument<T> .
Bu kod olmadan, eksik dosyalar özel durum ve yığın izlemesi ile bildirilir. Bu kodla yalnızca belirtilen hata iletisi görüntülenir.
Bu kod ayrıca varsayılan değeri belirtir ve bu nedenle olarak
true
ayarlanırisDefault
. olarak ayarlamazsanızisDefault
true
, için--file
giriş sağlanmazsaparseArgument
temsilci çağrılmıyordur.oluşturan
lightModeOption
koddan sonra vedelete
komutları içinadd
seçenekler ve bağımsız değişkenler ekleyin:var searchTermsOption = new Option<string[]>( name: "--search-terms", description: "Strings to search for when deleting entries.") { IsRequired = true, AllowMultipleArgumentsPerToken = true }; var quoteArgument = new Argument<string>( name: "quote", description: "Text of quote."); var bylineArgument = new Argument<string>( name: "byline", description: "Byline of quote.");
ayarı, AllowMultipleArgumentsPerToken listedeki öğeleri ilk öğeden sonra belirtirken seçenek adını atlamanıza
--search-terms
olanak tanır. Aşağıdaki komut satırı girişi örneklerini eşdeğer hale getirir:scl quotes delete --search-terms David "You can do" scl quotes delete --search-terms David --search-terms "You can do"
Kök komutu oluşturan kodu ve
read
komutunu aşağıdaki kodla değiştirin:var rootCommand = new RootCommand("Sample app for System.CommandLine"); rootCommand.AddGlobalOption(fileOption); var quotesCommand = new Command("quotes", "Work with a file that contains quotes."); rootCommand.AddCommand(quotesCommand); var readCommand = new Command("read", "Read and display the file.") { delayOption, fgcolorOption, lightModeOption }; quotesCommand.AddCommand(readCommand); var deleteCommand = new Command("delete", "Delete lines from the file."); deleteCommand.AddOption(searchTermsOption); quotesCommand.AddCommand(deleteCommand); var addCommand = new Command("add", "Add an entry to the file."); addCommand.AddArgument(quoteArgument); addCommand.AddArgument(bylineArgument); addCommand.AddAlias("insert"); quotesCommand.AddCommand(addCommand);
Bu kod aşağıdaki değişiklikleri yapar:
--file
seçeneğini komutundanread
kaldırır.--file
seçeneğini kök komutuna genel seçenek olarak ekler.Bir
quotes
komut oluşturur ve bunu kök komutuna ekler.read
komutunu kök komutuquotes
yerine komutuna ekler.Ve
delete
komutlarını oluştururadd
ve komutunaquotes
ekler.
Sonuç aşağıdaki komut hiyerarşisidir:
- Kök komutu
quotes
read
add
delete
Uygulama artık üst komutun (
quotes
) bir alanı veya grubu belirttiği ve alt komutlarının (read
,add
,delete
) eylemler olduğu önerilen deseni uygular.Genel seçenekler komuta uygulanır ve alt komutlara özyinelemeli olarak uygulanır.
--file
kök komutunda olduğundan, uygulamanın tüm alt komutlarında otomatik olarak kullanılabilir.Koddan
SetHandler
sonra yeni alt komutlar için yeni kod ekleyinSetHandler
:deleteCommand.SetHandler((file, searchTerms) => { DeleteFromFile(file!, searchTerms); }, fileOption, searchTermsOption); addCommand.SetHandler((file, quote, byline) => { AddToFile(file!, quote, byline); }, fileOption, quoteArgument, bylineArgument);
Alt komutun
quotes
bir işleyicisi yoktur çünkü yaprak komut değildir. ,add
ve alt komutlarıread
altındaquotes
yaprak komutlardır veSetHandler
her biri için çağrılırdelete
.ve
delete
işleyicileriniadd
ekleyin.internal static void DeleteFromFile(FileInfo file, string[] searchTerms) { Console.WriteLine("Deleting from file"); File.WriteAllLines( file.FullName, File.ReadLines(file.FullName) .Where(line => searchTerms.All(s => !line.Contains(s))).ToList()); } internal static void AddToFile(FileInfo file, string quote, string byline) { Console.WriteLine("Adding to file"); using StreamWriter? writer = file.AppendText(); writer.WriteLine($"{Environment.NewLine}{Environment.NewLine}{quote}"); writer.WriteLine($"{Environment.NewLine}-{byline}"); writer.Flush(); }
Tamamlanmış uygulama şöyle görünür:
using System.CommandLine;
namespace scl;
class Program
{
static async Task<int> Main(string[] args)
{
var fileOption = new Option<FileInfo?>(
name: "--file",
description: "An option whose argument is parsed as a FileInfo",
isDefault: true,
parseArgument: result =>
{
if (result.Tokens.Count == 0)
{
return new FileInfo("sampleQuotes.txt");
}
string? filePath = result.Tokens.Single().Value;
if (!File.Exists(filePath))
{
result.ErrorMessage = "File does not exist";
return null;
}
else
{
return new FileInfo(filePath);
}
});
var delayOption = new Option<int>(
name: "--delay",
description: "Delay between lines, specified as milliseconds per character in a line.",
getDefaultValue: () => 42);
var fgcolorOption = new Option<ConsoleColor>(
name: "--fgcolor",
description: "Foreground color of text displayed on the console.",
getDefaultValue: () => ConsoleColor.White);
var lightModeOption = new Option<bool>(
name: "--light-mode",
description: "Background color of text displayed on the console: default is black, light mode is white.");
var searchTermsOption = new Option<string[]>(
name: "--search-terms",
description: "Strings to search for when deleting entries.")
{ IsRequired = true, AllowMultipleArgumentsPerToken = true };
var quoteArgument = new Argument<string>(
name: "quote",
description: "Text of quote.");
var bylineArgument = new Argument<string>(
name: "byline",
description: "Byline of quote.");
var rootCommand = new RootCommand("Sample app for System.CommandLine");
rootCommand.AddGlobalOption(fileOption);
var quotesCommand = new Command("quotes", "Work with a file that contains quotes.");
rootCommand.AddCommand(quotesCommand);
var readCommand = new Command("read", "Read and display the file.")
{
delayOption,
fgcolorOption,
lightModeOption
};
quotesCommand.AddCommand(readCommand);
var deleteCommand = new Command("delete", "Delete lines from the file.");
deleteCommand.AddOption(searchTermsOption);
quotesCommand.AddCommand(deleteCommand);
var addCommand = new Command("add", "Add an entry to the file.");
addCommand.AddArgument(quoteArgument);
addCommand.AddArgument(bylineArgument);
addCommand.AddAlias("insert");
quotesCommand.AddCommand(addCommand);
readCommand.SetHandler(async (file, delay, fgcolor, lightMode) =>
{
await ReadFile(file!, delay, fgcolor, lightMode);
},
fileOption, delayOption, fgcolorOption, lightModeOption);
deleteCommand.SetHandler((file, searchTerms) =>
{
DeleteFromFile(file!, searchTerms);
},
fileOption, searchTermsOption);
addCommand.SetHandler((file, quote, byline) =>
{
AddToFile(file!, quote, byline);
},
fileOption, quoteArgument, bylineArgument);
return await rootCommand.InvokeAsync(args);
}
internal static async Task ReadFile(
FileInfo file, int delay, ConsoleColor fgColor, bool lightMode)
{
Console.BackgroundColor = lightMode ? ConsoleColor.White : ConsoleColor.Black;
Console.ForegroundColor = fgColor;
var lines = File.ReadLines(file.FullName).ToList();
foreach (string line in lines)
{
Console.WriteLine(line);
await Task.Delay(delay * line.Length);
};
}
internal static void DeleteFromFile(FileInfo file, string[] searchTerms)
{
Console.WriteLine("Deleting from file");
File.WriteAllLines(
file.FullName, File.ReadLines(file.FullName)
.Where(line => searchTerms.All(s => !line.Contains(s))).ToList());
}
internal static void AddToFile(FileInfo file, string quote, string byline)
{
Console.WriteLine("Adding to file");
using StreamWriter? writer = file.AppendText();
writer.WriteLine($"{Environment.NewLine}{Environment.NewLine}{quote}");
writer.WriteLine($"{Environment.NewLine}-{byline}");
writer.Flush();
}
}
Projeyi derleyin ve aşağıdaki komutları deneyin.
komutuyla read
öğesine var olmayan bir dosya --file
gönderin; özel durum ve yığın izlemesi yerine bir hata iletisi alırsınız:
scl quotes read --file nofile
File does not exist
Alt komutu quotes
çalıştırmayı denediğinizde , add
veya delete
kullanmaya read
yönlendiren bir ileti alırsınız:
scl quotes
Required command was not provided.
Description:
Work with a file that contains quotes.
Usage:
scl quotes [command] [options]
Options:
--file <file> An option whose argument is parsed as a FileInfo [default: sampleQuotes.txt]
-?, -h, --help Show help and usage information
Commands:
read Read and display the file.
delete Delete lines from the file.
add, insert <quote> <byline> Add an entry to the file.
alt komutunu add
çalıştırın ve eklenen metni görmek için metin dosyasının sonuna bakın:
scl quotes add "Hello world!" "Nancy Davolio"
Dosyanın başından itibaren arama dizeleriyle alt komutu delete
çalıştırın ve sonra metnin kaldırıldığı yeri görmek için metin dosyasının başına bakın:
scl quotes delete --search-terms David "You can do" Antoine "Perfection is achieved"
Not
bin/debug/net6.0 klasöründe çalıştırıyorsanız, ve komutlarındaki add
delete
değişiklikleri içeren dosyayı bu klasörde bulabilirsiniz. Proje klasöründeki dosyanın kopyası değişmeden kalır.
Sonraki adımlar
Bu öğreticide, kullanan System.CommandLine
basit bir komut satırı uygulaması oluşturdunuz. Kitaplık hakkında daha fazla bilgi edinmek için bkz System.CommandLine . genel bakış.