Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Tavsiye
Bu makale, en az bir programlama dili bilen ve C# dilini öğrenen geliştiriciler için yazılan Temel Bilgiler bölümünün bir parçasıdır. Programlamaya yeni başladıysanız Başlarken'i kullanmaya başlayın. Kapsamlı kitaplık kapsamına ihtiyacınız varsa System.CommandLine kitaplık belgelerine bakın.
Kitaplık System.CommandLine , uygulamanızın mantığına odaklanabilmeniz için komut satırı ayrıştırma, yardım metni oluşturma ve giriş doğrulama işlemlerini işler. Bu öğreticide, temel kavramları gösteren bir görev izleyici CLI'sı oluşturacaksınız: komutlar, alt komutlar, seçenekler ve bağımsız değişkenler.
Bu eğitimde, siz:
- paketini kullanarak
System.CommandLinedosya tabanlı bir uygulama oluşturun. - Yazılan değerlerle seçenekleri ve bağımsız değişkenleri tanımlayın.
- Alt komutlar oluşturun ve bunlara seçenekler ve bağımsız değişkenler ekleyin.
- Her alt komutu bir eylemle işleyin.
- Uygulamayı farklı komut satırı girişleriyle test edin.
Önkoşullar
- .NET 10 SDK'si veya üstünü yükleyin.
Uygulamayı oluşturma
Başlangıç olarak, bir dosya tabanlı C# programı oluşturun ve System.CommandLine paketini ekleyin.
Aşağıdaki içeriğe sahip adlı
TaskCli.csbir dosya oluşturun:#!/usr/bin/env dotnet#!(shebang) satırı, dosyayı doğrudan Unix sistemlerinde çalıştırmanıza olanak tanır. Windows'da dosyayıdotnet run TaskCli.csçalıştırın.Gerekli
System.CommandLinepaket yönergesini veusingdeyimlerini ekleyin.#:package System.CommandLine@2.0.0using System.CommandLine; using System.CommandLine.Parsing; using System.Text.Json;Önemli
Sürüm
2.0.0, yazma sırasındaki en son sürümdür. En son güvenlik düzeltmelerine sahip olduğunuzdan emin olmak için paketin NuGet sayfasında en son sürüme bakın.
Komut yapısını anlama
Herhangi bir ayrıştırma kodu yazmadan önce CLI'nin kullanıcı açısından nasıl göründüğünü göz önünde bulundurun. Görev izleyicisi dört işlemi destekler:
dotnet TaskCli.cs -- add "Write documentation" --priority High --due 2026-04-01
dotnet TaskCli.cs -- list --all
dotnet TaskCli.cs -- complete 3
dotnet TaskCli.cs -- remove 3
dotnet TaskCli.cs -- --verbose list
Uyarı
-- Yukarıdaki örneklerde TaskCli.cs sonrası yer alan dotnet run ifadesi, kalan tüm bağımsız değişkenlerin CLI tarafından yorumlanmak yerine, uygulamanıza iletildiğini bildirirdotnet.
Her satırda birkaç komut satırı kavramı kullanılır:
-
Alt komutlar , uygulamaya ne yapacağını belirten fiillerdir. Görev izleyicisinin dört tane vardır:
add,list,completeveremove. Her alt komut kendi parametrelerini tanımlayabilir. -
Bağımsız değişkenler , bir alt komutu izleyen konumsal değerlerdir.
add "Write documentation"içinde, string"Write documentation", görev açıklamasını belirten bir bağımsız değişkendir.complete 3, sayısı3, görev kimliğini belirten bir argümandır. -
Seçenekler
--ile öneklenmiş adlandırılmış değerlerdir.add --priority High --due 2026-04-01içinde, hem--priorityhem de--duekendi değerlerine sahip seçeneklerdir.list --alliçinde--allseçeneği, değer gerektirmeyen bir Boole bayrağıdır. -
Genel seçenekler her alt komut için geçerlidir. seçeneği
--verboseileRecursive = truekök komutunda tanımlanır, bu nedenle herhangi bir alt komutla çalışır.--verbose list'da, verbose bayrağı alt komutun önünde görünür, ancaklist --verbosede eşit derecede iyi çalışır.
İzleyen bölümlerde bu parçaları aşağıdan yukarıya doğru oluşturursunuz. İlk olarak, tek tek seçenekleri (ve gibi --priority--all) ve bağımsız değişkenleri (görev açıklaması ve kimlik gibi) tanımlarsınız. Ardından, dört alt komutu oluşturur ve her birine ilgili seçenekleri ve bağımsız değişkenleri eklersiniz. Ardından, her alt komut için bir eylem tanımlarsınız. Eylem, kullanıcı bu komutu çağırdığında çalışan koddur. Son olarak kök komutunu derler, girişi ayrıştırıp eşleşen eylemi çağırırsınız.
Komut satırı söz dizimi kavramlarına daha ayrıntılı bir bakış için bkz. Komut satırı söz dizimine genel bakış.
Seçenekleri ve bağımsız değişkenleri tanımlama
Seçenekler, kullanıcıların ön -- ek ile belirttiği adlandırılmış değerleri temsil eder. Bağımsız değişkenler pozisyonel değerleri temsil eder. Her ikisi de güçlü şekilde türlenmiştir.
System.CommandLine giriş dizesini belirttiğiniz türe ayrıştırıyor.
Kütüphane, System.CommandLine tür güvenliğini sağlamak için genel türleri kullanır. yazdığınızda Option<int>int köşeli ayraçlar arasındaki değer bir tür bağımsız değişkenidir. Kitaplığa seçeneğin ne tür bir değer içerdiğini bildirir. Sınıfın kendisi bir tür parametresiT (içinde System.CommandLine.Option<T>olduğu gibi) bildirir ve bir örnek oluşturduğunuzda somut türü sağlarsınız. Kitaplık, kullanıcının giriş dizesini ayrıştırarak otomatik olarak bu türe dönüştürür. Kullanıcı bir --delay abcsağlarsaOption<int>, System.CommandLine kodunuza hatalı veri geçirmek yerine ayrıştırma hatası bildirir. Aşağıdaki adımlarda , Option<bool>, Option<Priority>ve Option<DateOnly?> ile System.CommandLine.Argument<T>bu deseni görürsünüz. Genel bilgiler hakkında daha fazla bilgi için bkz . Genel değerler.
Seçenekleri tanımlayın. Her
Option<T>bir değer türünü, adı ve açıklamayı belirtir.--priorityseçeneği birenumtürü kullanır veSystem.CommandLinegirdisini, geçerli enum değerlerine göre otomatik olarak doğrular.var verboseOption = new Option<bool>("--verbose") { Description = "Show detailed output", Recursive = true }; var priorityOption = new Option<Priority>("--priority") { Description = "Task priority level", DefaultValueFactory = _ => Priority.Medium }; var dueOption = new Option<DateOnly?>("--due") { Description = "Due date (uses current culture date format)" }; var allOption = new Option<bool>("--all") { Description = "Include completed tasks" };Recursive = trueayarı,--verboseseçeneğini her alt komutta kullanılabilir hale getirir.--priorityüzerindekiDefaultValueFactory, kullanıcıların seçeneği geçersiz kılabilmesi için varsayılan bir değer sağlar.Bağımsız değişkenleri tanımlayın. Her
Argument<T>bir değer türünü ve bir adı belirtir:var descriptionArgument = new Argument<string>("description") { Description = "Task description" }; var taskIdArgument = new Argument<int>("id") { Description = "Task ID" };
Kurulum komutları ve alt komutları
A System.CommandLine.Command , kullanıcının çağırabileceği bir eylemi temsil eder. Her komut için System.CommandLine hangi parametrelerin nereye ait olduğunu anlaması amacıyla ilgili seçenekleri ve bağımsız değişkenleri ekleyin.
Dört alt komutu oluşturun. Her komut kendi seçenek ve bağımsız değişken bileşimini alır:
var addCommand = new Command("add", "Add a new task") { Arguments = { descriptionArgument }, Options = { priorityOption, dueOption } };var listCommand = new Command("list", "List all tasks") { Options = { allOption } };var completeCommand = new Command("complete", "Mark a task as complete") { Arguments = { taskIdArgument } };var removeCommand = new Command("remove", "Remove a task") { Arguments = { taskIdArgument } };Kök komutunu derleyin. System.CommandLine.RootCommand, CLI için giriş noktasıdır. Genel
--verboseseçeneği ve tüm alt komutları ekleyin:var rootCommand = new RootCommand("A simple task tracker CLI") { Options = { verboseOption }, Subcommands = { addCommand, listCommand, completeCommand, removeCommand } };Otomatik oluşturulan yardım metni, kullanıcı tarafından çalıştırıldığında
TaskCli --helpkök komut açıklamasını gösterir.
Komutları eylemlerle yönetme
Her alt komutun bir eyleme ihtiyacı vardır. Eylem, kullanıcı bu komutu çağırdığında çalışan bir temsilcidir . Delege, bir yönteme referans veren bir türdür. Burada, temsilci olarak bir lambda ifadesi (bir => ile tanımlanan satır içi anonim işlev) geçirirsiniz. Her eylemi atamak için SetAction çağır. Temsilci, ParseResult aracılığıyla ayrıştırılan değerlere GetValue ile erişim sağlar.
Komutun eylemini
addayarlayın. Bu eylem, dize enterpolasyonu ($"..."küme ayraçlarına ifadeler gömen dizeler), koşullu işlemci (?:) ve null atanabilir bir değerin değeri olup olmadığını denetleyen ve bunu tek adımda yeni bir değişkene atayan bir tür testi deseni (due is DateOnly dueDate) tanıtır.addCommand.SetAction(parseResult => { var description = parseResult.GetValue(descriptionArgument)!; var priority = parseResult.GetValue(priorityOption); var due = parseResult.GetValue(dueOption); var verbose = parseResult.GetValue(verboseOption); var tasks = LoadTasks(); var id = tasks.Count > 0 ? tasks.Max(t => t.Id) + 1 : 1; var task = new TaskItem(id, description, priority, due, false); tasks.Add(task); SaveTasks(tasks); Console.WriteLine($"Added task {id}: {description}"); if (verbose) { Console.WriteLine($" Priority: {priority}"); if (due is DateOnly dueDate) { Console.WriteLine($" Due: {dueDate}"); } } });listkomutu için eylemi ayarlayın. LINQ (Dil Tümleşik Sorgu), bellek içi koleksiyonlar için standart sorgu işleçleri sağlar. Bu eylemde, Enumerable.Where görevleri yalnızca bir koşulla eşleşen öğelere filtreler ve Enumerable.ToList filtrelenmiş diziyi bir listeye uygular. Eylem daha sonra sonuçları yinelemek için birforeachdöngü ve durum simgesi seçmek için koşullu işleç kullanır:listCommand.SetAction(parseResult => { var showAll = parseResult.GetValue(allOption); var verbose = parseResult.GetValue(verboseOption); var tasks = LoadTasks(); var filtered = showAll ? tasks : tasks.Where(t => !t.IsComplete).ToList(); if (filtered.Count == 0) { Console.WriteLine("No tasks found."); return; } foreach (var task in filtered) { var status = task.IsComplete ? "✓" : " "; Console.WriteLine($" [{status}] {task.Id}: {task.Description}"); if (verbose) { Console.WriteLine($" Priority: {task.Priority}"); if (task.Due is DateOnly dueDate) { Console.WriteLine($" Due: {dueDate}"); } } } });Daha fazla ayrıntı için bkz. LINQ.
completekomutunun eylemini ayarlayın. Bu eylem, bulmak için LINQ'leri Enumerable.FirstOrDefault kullanır:- Eşleştirme görevi.
- Görevin var olup olmadığını denetlemek için kullanılan bir desen.
is null - Önce
withmevcut değerleri kopyalayıp ardından başlatıcıdawithayarladığınız özellikleri uygulayarak yeni bir kayıt örneği oluşturmaya yönelik ifade (burada,IsComplete = true). Kayıtlar varsayılan olarak sabittir, bu nedenle bu kopyalama ve güncelleştirme düzeni değiştirilmiş bir değeri nasıl oluşturduğunuzdur.
Eylem başarısız olabileceğinden (örneğin, görev kimliği mevcut olmadığından), eylem uygulamanın çıkış koduna dönüşen bir tamsayı hata kodu döndürür:
completeCommand.SetAction(parseResult => { var id = parseResult.GetValue(taskIdArgument); var verbose = parseResult.GetValue(verboseOption); var tasks = LoadTasks(); var task = tasks.FirstOrDefault(t => t.Id == id); if (task is null) { Console.Error.WriteLine($"Task {id} not found."); return -1; } tasks[tasks.IndexOf(task)] = task with { IsComplete = true }; SaveTasks(tasks); Console.WriteLine($"Completed task {id}: {task.Description}"); if (verbose) { Console.WriteLine($" Priority: {task.Priority}"); } return 0; });removekomutunun eylemini ayarlayın. Bu eylem,completeile aynı arama ve doğrulama kalıbını izler. GöreviFirstOrDefaultbulmak ve eksik durumu işlemek içinis nullkullanın.removeCommand.SetAction(parseResult => { var id = parseResult.GetValue(taskIdArgument); var verbose = parseResult.GetValue(verboseOption); var tasks = LoadTasks(); var task = tasks.FirstOrDefault(t => t.Id == id); if (task is null) { Console.Error.WriteLine($"Task {id} not found."); return -1; } tasks.Remove(task); SaveTasks(tasks); Console.WriteLine($"Removed task {id}: {task.Description}"); if (verbose) { Console.WriteLine($" Priority: {task.Priority}"); } return 0; });Komut satırını ayrıştırın ve eşleşen eylemi çağırın:
return rootCommand.Parse(args).Invoke();rootCommand.Parse(args), girişi ParseResult olarak ayrıştırır ve.Invoke(), eşleşen komut için eylemi çalıştırır. Dönüş değeri bir çıkış kodudur (başarı için 0).
Destekleyici türler ve veri yardımcıları ekleme
Uygulamanın birkaç destekleyici parçaya ihtiyacı vardır: yerel işlevler, bir enum, bir recordve bir serileştirme bağlamı. Aşağıdaki bölümlerde her bir kavram tanıtılarak, neden seçeceğiniz açıklanır ve kod gösterilir. Uygulama, görevleri JSON (JavaScript Nesne Gösterimi) olarak depolamak için System.Text.Json kullanır. Dosya tabanlı uygulamalar, tüm üst düzey deyimlerden ve yerel işlevlerden sonra tür bildirimlerinin gösterilmesini gerektirir.
Görevleri yükleyip kaydeden yerel işlevleri ekleyin. Yerel işlev, diğer yerel işlevlerin içinde de dahil olmak üzere başka bir işlev içinde bildirilen bir yöntemdir. Yerel işlevler yardımcı mantığı çağıran koda yakın tutar ve böylece okuyucunun akışı anlamak için ayrı bir sınıfa veya dosyaya atlaması gerekmeyen okunabilirliği artırır. Burada
LoadTasksveSaveTasks, birden fazla komut işleminin paylaştığı dosya G/Ç'sini kapsüller, böylece uygulama yükleme/kaydetme mantığını bir kez yazar ve yeniden kullanır.static string GetTaskFilePath() => Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "taskcli-sample", "tasks.json"); static List<TaskItem> LoadTasks() { var path = GetTaskFilePath(); if (!File.Exists(path)) { return []; } var json = File.ReadAllText(path); return JsonSerializer.Deserialize(json, TaskJsonContext.Default.ListTaskItem) ?? []; } static void SaveTasks(List<TaskItem> tasks) { var path = GetTaskFilePath(); Directory.CreateDirectory(Path.GetDirectoryName(path)!); var json = JsonSerializer.Serialize(tasks, TaskJsonContext.Default.ListTaskItem); File.WriteAllText(path, json); }Dosyanın sonuna
Priorityenum veTaskItemrecord ekleyin:public enum Priority { Low, Medium, High },
enumtamsayı türü tarafından desteklenen sabit bir adlandırılmış sabit kümesini tanımlayan bir değer türüdür. Öncelik düzeylerini düz tamsayılarla (0, 1, 2) temsil edebilirsiniz, ancak birkaçenumnedenden dolayı daha iyi bir seçimdir: derleyici atamaları tanımlı adlarla kısıtlar, bu nedenle gibiHihgbir yazım hatası sessiz bir hata yerine derleme zamanı hatasına neden olur; adlarıLow,MediumveHighkodu daha okunabilir hale getirir veSystem.CommandLinekullanıcı girişini sabit listesi üyelerine karşı otomatik olarak doğrular, böylece ücretsiz giriş denetimi elde edersiniz.public record TaskItem(int Id, string Description, Priority Priority, DateOnly? Due, bool IsComplete);A
record, derleyicinin değer tabanlı eşitlik ve yıkıcı olmayan mutasyon ile donatdığı bir türdür.recordTaskItemiçin en uygun olanıdır, çünkü görev verileri karmaşık bir davranış içermeyen basit bir durumdur—görevleri başvuru kimliğine göre değil, değerlerine göre karşılaştırırsınız. Derleyici, oluşturucu parametrelerindenEquals,GetHashCode,ToStringvewithifade desteği üretir, böylece şablon kod yazmadan doğru eşitlik denetimleri, kolay hata ayıklama çıktısını ve değiştirilemez güncellemeler alırsınız. Kayıtlar varsayılan olarak sabit olduğundan, orijinal öğeyi değiştirmek yerine değiştirilmiş bir kopya (tıpkıcompleteifadesinin yaptığı gibi) üretmek için birwithifade kullanırsınız. Bu, farklı eylemler aynı listeyi okurken ve yazarken yanlışlıkla yan etkileri önler.AOT uyumlu serileştirme için JSON serileştirme bağlamını ekleyin:
[System.Text.Json.Serialization.JsonSourceGenerationOptions(WriteIndented = true)] [System.Text.Json.Serialization.JsonSerializable(typeof(List<TaskItem>))] internal partial class TaskJsonContext : System.Text.Json.Serialization.JsonSerializerContext;Bu sınıf iki öznitelik (bir bildirimin üzerindeki köşeli ayraçlara yerleştirilen meta veri ek açıklamaları) kullanır. özniteliği,
[JsonSourceGenerationOptions(WriteIndented = true)]kaynak oluşturucuya okunabilirlik için girintili JSON yaymasını söyler.[JsonSerializable(typeof(List<TaskItem>))]özniteliği, oluşturucuya serileştirme kodunun oluşturulacağı türü bildirir. Bu öznitelikler birlikte, çalışma zamanı yansımasını önleyen ve önceden (AOT) derlemeyi destekleyen kaynak tarafından oluşturulan serileştirmeyi etkinleştirir.
Uygulamayı test et
Her alt komutu uygulamak için uygulamayı farklı girişlerle çalıştırın.
Otomatik oluşturulan yardımı görüntüleyin:
dotnet run TaskCli.cs -- --helpDescription: A simple task tracker CLI Usage: TaskCli [command] [options] Options: --verbose Show detailed output -?, -h, --help Show help and usage information --version Show version information Commands: add <description> Add a new task list List all tasks complete <id> Mark a task as complete remove <id> Remove a taskFarklı seçeneklere sahip görevler ekleyin:
dotnet run TaskCli.cs -- add "Write documentation" --priority High --due 2026-04-01 dotnet run TaskCli.cs -- add "Review pull request" dotnet run TaskCli.cs -- add "Fix build errors"Added task 1: Write documentation Added task 2: Review pull request Added task 3: Fix build errorsGörevleri listeleyin ve ek ayrıntıları göstermek için kullanın
--verbose:dotnet run TaskCli.cs -- --verbose list[ ] 1: Write documentation Priority: High Due: 4/1/2026 [ ] 2: Review pull request Priority: Medium [ ] 3: Fix build errors Priority: MediumBir görevi tamamlayın, ardından listenin tamamlanan görevleri varsayılan olarak filtrelediğinden emin olun:
dotnet run TaskCli.cs -- complete 2 dotnet run TaskCli.cs -- listCompleted task 2: Review pull request [ ] 1: Write documentation [ ] 3: Fix build errorsTamamlanmış görevleri eklemek için kullanın
--all:dotnet run TaskCli.cs -- list --all[ ] 1: Write documentation [✓] 2: Review pull request [ ] 3: Fix build errorsGörevi kaldırma:
dotnet run TaskCli.cs -- remove 3Removed task 3: Fix build errors
Kaynakları temizle
Görev izleyicisi verileri yerel uygulama veri klasörünüz altındaki bir JSON dosyasında depolar.
taskcli-sample Örnek verileri kaldırmak için klasörü silin:
-
Windows: silin
%LOCALAPPDATA%\taskcli-sample. -
macOS: silin
~/Library/Application Support/taskcli-sample. -
Linux: silin
~/.local/share/taskcli-sample.