Aracılığıyla paylaş


Öğretici: System.CommandLine kullanmaya başlama

Önemli

System.CommandLine şu anda ÖNİzLEME aşamasındadır ve bu belge 2.0 beta 5 sürümüne yöneliktir. Bazı bilgiler, yayımlanmadan önce önemli ölçüde değiştirilebilen yayın öncesi ürünle ilgilidir. Microsoft, burada sağlanan bilgilerle ilgili olarak açık veya zımni hiçbir garanti vermez.

Bu öğreticide, System.CommandLine kitaplığını kullanan bir .NET komut satırı uygulamasının nasıl oluşturulacağı gösterilmektedir. İlk olarak tek bir seçeneği olan basit bir kök komutu oluşturacaksınız. Ardından bu temeli oluşturacak 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 aşağıdakilerin nasıl yapılacağı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.
  • Komut altındaki tüm alt komutlara özyinelemeli olarak bir seçenek atayın.
  • Birden fazla katmanlı iç içe geçmiş alt komutlarla çalışma.
  • Komutlar ve seçenekler için diğer adlar oluşturun.
  • string, string[], int, bool, FileInfo ve sabit listesi seçenek türleriyle birlikte çalışın.
  • Komut eylem kodundaki seçenek değerlerini okuyun.
  • Seçenekleri ayrıştırma ve doğrulama için özel kod kullanın.

Önkoşullar

Veya

Uygulamayı oluşturma

"scl" adlı bir .NET 9 konsol uygulaması projesi oluşturun.

  1. Proje için scl adlı bir klasör oluşturun ve ardından yeni klasörde bir komut istemi açın.

  2. Aşağıdaki komutu çalıştırın:

    dotnet new console --framework net9.0
    

System.CommandLine paketini yükleme

  • Aşağıdaki komutu çalıştırın:

    dotnet add package System.CommandLine --prerelease
    

    Veya .NET 10+'da:

    dotnet package add System.CommandLine --prerelease
    

    Kitaplık hala beta sürümünde olduğundan --prerelease seçeneği gereklidir.

Argümanları ayrıştır

  1. Program.cs dosyasının içeriğini aşağıdaki kodla değiştirin:

    using System.CommandLine;
    using System.CommandLine.Parsing;
    
    namespace scl;
    
    class Program
    {
        static int Main(string[] args)
        {
            Option<FileInfo> fileOption = new("--file")
            {
                Description = "The file to read and display on the console."
            };
    
            RootCommand rootCommand = new("Sample app for System.CommandLine");
            rootCommand.Options.Add(fileOption);
    
            ParseResult parseResult = rootCommand.Parse(args);
            if (parseResult.GetValue(fileOption) is FileInfo parsedFile)
            {
                ReadFile(parsedFile);
                return 0;
            }
            foreach (ParseError parseError in parseResult.Errors)
            {
                Console.Error.WriteLine(parseError.Message);
            }
            return 1;
        }
    
        static void ReadFile(FileInfo file)
        {
            foreach (string line in File.ReadLines(file.FullName))
            {
                Console.WriteLine(line);
            }
        }
    }
    

Önceki kod:

Option<FileInfo> fileOption = new("--file")
{
    Description = "The file to read and display on the console."
};

RootCommand rootCommand = new("Sample app for System.CommandLine");
rootCommand.Options.Add(fileOption);
  • args öğesini ayrıştırır ve --file seçeneği için herhangi bir değer sağlanıp sağlanmadığını kontrol eder. Bu durumda, ayrıştırılmış değeri kullanarak yöntemini çağırır ReadFile ve çıkış kodunu döndürür 0 :
ParseResult parseResult = rootCommand.Parse(args);
if (parseResult.GetValue(fileOption) is FileInfo parsedFile)
{
    ReadFile(parsedFile);
    return 0;
}
  • için --filedeğer sağlanmadıysa, kullanılabilir ayrıştırma hatalarını yazdırır ve çıkış kodunu döndürür 1 :
foreach (ParseError parseError in parseResult.Errors)
{
    Console.Error.WriteLine(parseError.Message);
}
return 1;
  • yöntemi belirtilen ReadFile dosyayı okur ve içeriğini konsolunda görüntüler:
static void ReadFile(FileInfo file)
{
    foreach (string line in File.ReadLines(file.FullName))
    {
        Console.WriteLine(line);
    }
}

Uygulamayı test edin

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/net9.0 klasöründe bir komut istemi açın:

    dotnet build
    cd bin/Debug/net9.0
    scl --file scl.runtimeconfig.json
    
  • Aşağıdaki örnekte olduğu gibi dotnet run kullanın ve seçenek değerlerini runsonrasına ekleyerek -- komutu yerine uygulamaya geçirin:

    dotnet run -- --file bin/Debug/net9.0/scl.runtimeconfig.json
    

Bu öğreticide, bu seçeneklerden ilkini kullandığınız varsayılır.

Uygulamayı çalıştırdığınızda, --file seçeneği tarafından belirtilen dosyanın içeriğini görüntüler.

{
  "runtimeOptions": {
    "tfm": "net9.0",
    "framework": {
      "name": "Microsoft.NETCore.App",
      "version": "9.0.0"
    }
  }
}

Peki ya yardım görüntülemesini --help sağlayarak isterseniz ne olur? Uygulama, --file sağlanmadığı ve ayrıştırma hataları olmadığı durumda senaryoyu henüz ele almadığı için konsola hiçbir şey yazdırılmaz.

Bağımsız değişkenleri ayrıştır ve ParseResult'ı çağır

System.CommandLine belirli bir simge (komut, yönerge veya seçenek) başarıyla ayrıştırıldığında çağrılan bir eylem belirtmenize olanak tanır. Eylem, System.CommandLine.ParseResult parametresini alan ve bir int çıkış kodu döndüren bir temsilcidir (asenkron eylemler de mevcuttur). Çıkış kodu yöntemi tarafından döndürülür ve komutun System.CommandLine.Parsing.ParseResult.Invoke başarıyla yürütülerek yürütülmediğini belirtmek için kullanılabilir.

  1. Program.cs dosyasının içeriğini aşağıdaki kodla değiştirin:

    using System.CommandLine;
    
    namespace scl;
    
    class Program
    {
        static int Main(string[] args)
        {
            Option<FileInfo> fileOption = new("--file")
            {
                Description = "The file to read and display on the console."
            };
    
            RootCommand rootCommand = new("Sample app for System.CommandLine");
            rootCommand.Options.Add(fileOption);
    
            rootCommand.SetAction(parseResult =>
            {
                FileInfo parsedFile = parseResult.GetValue(fileOption);
                ReadFile(parsedFile);
                return 0;
            });
    
            ParseResult parseResult = rootCommand.Parse(args);
            return parseResult.Invoke();
        }
    
        static void ReadFile(FileInfo file)
        {
            foreach (string line in File.ReadLines(file.FullName))
            {
                Console.WriteLine(line);
            }
        }
    }
    

Önceki kod:

  • ReadFile Kök komut çağrıldığında çağrılacak yöntemin bu olduğunu belirtir:

    rootCommand.SetAction(parseResult =>
    {
        FileInfo parsedFile = parseResult.GetValue(fileOption);
        ReadFile(parsedFile);
        return 0;
    });
    
  • args ayrıştırılır ve sonucu çağırılır:

    ParseResult parseResult = rootCommand.Parse(args);
    return parseResult.Invoke();
    

Uygulamayı çalıştırdığınızda, --file seçeneği tarafından belirtilen dosyanın içeriğini görüntüler.

--help komutunu sağlayarak yardımın görüntülenmesini istediğinizde ne olur?

scl --help

Aşağıdaki çıktı yazdırılır:

Description:
  Sample app for System.CommandLine

Usage:
  scl [options]

Options:
  -?, -h, --help  Show help and usage information
  --version       Show version information
  --file          The file to read and display on the conso

System.CommandLine.RootCommand varsayılan olarak Yardım seçeneği, Sürüm seçeneği ve Öneri yönergesi sağlar. ParseResult.Invoke yöntemi, ayrıştırılmış simgenin eylemini çağırmaktan sorumludur. Bu, komutumuz için açıkça tanımlanan eylem veya System.CommandLine tarafından System.CommandLine.Help.HelpOption için tanımlanan yardım eylemi olabilir. Ayrıca, ayrıştırma hataları algıladığında bunları standart hataya yazdırır, standart çıkışa yardım yazdırır ve çıkış kodunu döndürür 1 :

scl --invalid bla
Unrecognized command or argument '--invalid'.
Unrecognized command or argument 'bla'.

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ı öğreticisindengelen bir alıntı koleksiyonunu okumak için kullanılacaktır.

  1. Bu örneğin GitHub deposundaki sampleQuotes.txt dosyasını proje dizininize kopyalayın. Dosyaları indirme hakkında bilgi için Örnekler ve Öğreticileryönergelerine bakın.

  2. Proje dosyasını açın ve kapanış <ItemGroup> etiketinden hemen önce bir </Project> öğesi ekleyin:

    <ItemGroup>
      <Content Include="sampleQuotes.txt">
        <CopyToOutputDirectory>Always</CopyToOutputDirectory>
      </Content>
    </ItemGroup>
    

    Bu işaretlemenin eklenmesi, uygulamayı oluştururken metin dosyasının bin/debug/net9.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.

  3. Program.csiçinde, --file seçeneğini oluşturan koddan sonra, okuma hızını ve metin renklerini denetlemek için seçenekler oluşturun:

    Option<int> delayOption = new("--delay")
    {
        Description = "Delay between lines, specified as milliseconds per character in a line.",
        DefaultValueFactory = parseResult => 42
    };
    Option<ConsoleColor> fgcolorOption = new("--fgcolor")
    {
        Description = "Foreground color of text displayed on the console.",
        DefaultValueFactory = parseResult => ConsoleColor.White
    };
    Option<bool> lightModeOption = new("--light-mode")
    {
        Description = "Background color of text displayed on the console: default is black, light mode is white."
    };
    
  4. Kök komutu oluşturan satırdan sonra seçeneği ekleyen --file kodu silin. Burada kaldırıyorsunuz çünkü yeni bir alt komuta ekleyeceksiniz.

  5. Kök komutu oluşturan satırdan sonra bir read alt komutu oluşturun. Bu alt komuta seçenekleri ekleyin (özellik yerine Options koleksiyon başlatıcı söz dizimini kullanarak) ve alt komutu kök komutuna ekleyin.

    Command readCommand = new("read", "Read and display the file.")
    {
        fileOption,
        delayOption,
        fgcolorOption,
        lightModeOption
    };
    rootCommand.Subcommands.Add(readCommand);
    
  6. SetAction kodunu yeni alt komut için aşağıdaki SetAction koduyla değiştirin:

    readCommand.SetAction(parseResult => ReadFile(
        parseResult.GetValue(fileOption),
        parseResult.GetValue(delayOption),
        parseResult.GetValue(fgcolorOption),
        parseResult.GetValue(lightModeOption)));
    

    Kök komutun artık bir eyleme ihtiyacı kalmadığından, kök komutta SetAction artık çağırmıyorsunuz. Bir komutun alt komutları olduğunda, genellikle bir komut satırı uygulaması çağrılırken alt komutlardan birini belirtmeniz gerekir.

  7. ReadFile eylem yöntemini aşağıdaki kodla değiştirin:

    internal static void ReadFile(FileInfo file, int delay, ConsoleColor fgColor, bool lightMode)
    {
        Console.BackgroundColor = lightMode ? ConsoleColor.White : ConsoleColor.Black;
        Console.ForegroundColor = fgColor;
        foreach (string line in File.ReadLines(file.FullName))
        {
            Console.WriteLine(line);
            Thread.Sleep(TimeSpan.FromMilliseconds(delay * line.Length));
        }
    }
    

Uygulama şimdi şöyle görünür:

using System.CommandLine;

namespace scl;

class Program
{
    static int Main(string[] args)
    {
        Option<FileInfo> fileOption = new("--file")
        {
            Description = "The file to read and display on the console."
        };

        Option<int> delayOption = new("--delay")
        {
            Description = "Delay between lines, specified as milliseconds per character in a line.",
            DefaultValueFactory = parseResult => 42
        };
        Option<ConsoleColor> fgcolorOption = new("--fgcolor")
        {
            Description = "Foreground color of text displayed on the console.",
            DefaultValueFactory = parseResult => ConsoleColor.White
        };
        Option<bool> lightModeOption = new("--light-mode")
        {
            Description = "Background color of text displayed on the console: default is black, light mode is white."
        };

        RootCommand rootCommand = new("Sample app for System.CommandLine");

        Command readCommand = new("read", "Read and display the file.")
        {
            fileOption,
            delayOption,
            fgcolorOption,
            lightModeOption
        };
        rootCommand.Subcommands.Add(readCommand);

        readCommand.SetAction(parseResult => ReadFile(
            parseResult.GetValue(fileOption),
            parseResult.GetValue(delayOption),
            parseResult.GetValue(fgcolorOption),
            parseResult.GetValue(lightModeOption)));

        return rootCommand.Parse(args).Invoke();
    }

    internal static void ReadFile(FileInfo file, int delay, ConsoleColor fgColor, bool lightMode)
    {
        Console.BackgroundColor = lightMode ? ConsoleColor.White : ConsoleColor.Black;
        Console.ForegroundColor = fgColor;
        foreach (string line in File.ReadLines(file.FullName))
        {
            Console.WriteLine(line);
            Thread.Sleep(TimeSpan.FromMilliseconds(delay * line.Length));
        }
    }
}

Yeni alt komutu test edin

Şimdi alt komutu belirtmeden uygulamayı çalıştırmaya çalışırsanız, 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:
  -?, -h, --help  Show help and usage information
  --version       Show version information

Commands:
  read  Read and display the file.

Alt komut read için yardım metni dört seçeneğin kullanılabilir olduğunu gösterir. Enum 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

Sadece read seçeneğini belirterek alt komutu --file ç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, yavaş bir okuma hızına neden olur. --delay daha düşük bir sayıya ayarlayarak hızlandırabilirsiniz.

scl read --file sampleQuotes.txt --delay 0

Metin renklerini ayarlamak için --fgcolor ve --light-mode kullanabilirsiniz:

scl read --file sampleQuotes.txt --fgcolor red --light-mode

--delay için geçersiz bir değer sağladığınızda bir 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'.

--file için geçersiz bir değer sağlarsanız bir özel durum alırsınız:

scl read --file nofile
Unhandled exception: System.IO.FileNotFoundException: Could not find file 'C:\bin\Debug\net9.0\nofile''.
File name: 'C:\bin\Debug\net9.0\nofile''

Alt komutlar ve özel doğrulama ekleme

Bu bölüm, uygulamanın son sürümünü oluşturur. tamamlandığında, uygulama aşağıdaki komutlara ve seçeneklere sahip olur:

  • adlı özyinelemeli* seçeneğiyle root komutu --file
    • quotes komutu
      • read, --delayve --fgcolor adlı seçenekleri içeren --light-mode komutu
      • add ve quote adlı bağımsız değişkenlerle byline komutu
      • delete adlı seçeneği içeren --search-terms komutu

* Komuta ve onun tüm alt komutlarına özyinelemeli bir seçenek mevcuttur.

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"
  1. Program.csiçinde, --file seçeneğini oluşturan kodu aşağıdaki kodla değiştirin:

    Option<FileInfo> fileOption = new("--file")
    {
        Description = "An option whose argument is parsed as a FileInfo",
        Required = true,
        DefaultValueFactory = result =>
        {
            if (result.Tokens.Count == 0)
            {
                return new FileInfo("sampleQuotes.txt");
    
            }
            string filePath = result.Tokens.Single().Value;
            if (!File.Exists(filePath))
            {
                result.AddError("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 System.CommandLine.Parsing.ArgumentResult kullanır.

    Bu kod olmadan, eksik dosyalar hata mesajı ve yığın izi ile bildirilir. Bu kodla yalnızca belirtilen hata iletisi görüntülenir.

    Bu kod ayrıca varsayılan bir değer belirtir ve bu nedenle özel ayrıştırma yöntemine ayarlanır DefaultValueFactory .

  2. lightModeOptionoluşturan koddan sonra add ve delete komutları için seçenekler ve bağımsız değişkenler ekleyin:

    Option<string[]> searchTermsOption = new("--search-terms")
    {
        Description = "Strings to search for when deleting entries.",
        Required = true,
        AllowMultipleArgumentsPerToken = true
    };
    Argument<string> quoteArgument = new("quote")
    {
        Description = "Text of quote."
    };
    Argument<string> bylineArgument = new("byline")
    {
        Description = "Byline of quote."
    };
    

    xref:System.CommandLine.Option.AllowMultipleArgumentsPerToken ayarı, listede ilk öğeden sonra öğe belirtirken --search-terms seçenek adını atlamanıza 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"
    
  3. Kök komutu oluşturan kodu ve read komutunu aşağıdaki kodla değiştirin:

    RootCommand rootCommand = new("Sample app for System.CommandLine");
    fileOption.Recursive = true;
    rootCommand.Options.Add(fileOption);
    
    Command quotesCommand = new("quotes", "Work with a file that contains quotes.");
    rootCommand.Subcommands.Add(quotesCommand);
    
    Command readCommand = new("read", "Read and display the file.")
    {
        delayOption,
        fgcolorOption,
        lightModeOption
    };
    quotesCommand.Subcommands.Add(readCommand);
    
    Command deleteCommand = new("delete", "Delete lines from the file.");
    deleteCommand.Options.Add(searchTermsOption);
    quotesCommand.Subcommands.Add(deleteCommand);
    
    Command addCommand = new("add", "Add an entry to the file.");
    addCommand.Arguments.Add(quoteArgument);
    addCommand.Arguments.Add(bylineArgument);
    addCommand.Aliases.Add("insert");
    quotesCommand.Subcommands.Add(addCommand);
    

    Bu kod aşağıdaki değişiklikleri yapar:

    • --file komutundan read seçeneğini kaldırır.

    • seçeneğini kök komutuna --file özyinelemeli seçenek olarak ekler.

    • bir quotes komutu oluşturur ve bunu kök komutuna ekler.

    • read komutunu kök komutu yerine quotes komutuna ekler.

    • add ve delete komutları oluşturur ve bunları quotes komutuna ekler.

    Sonuç aşağıdaki komut hiyerarşisidir:

    • Kök komutu
      • quotes
        • read
        • add
        • delete

    Uygulama artık üst komutun () bir alanı veya grubu belirttiği ve alt komutlarının (quotes, read, add) eylemler olduğu delete düzeni uygular.

    Özyinelemeli 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.

  4. SetAction kodundan sonra, yeni alt komutlar için yeni SetAction kodu ekleyin:

    deleteCommand.SetAction(parseResult => DeleteFromFile(
        parseResult.GetValue(fileOption),
        parseResult.GetValue(searchTermsOption)));
    
    addCommand.SetAction(parseResult => AddToFile(
        parseResult.GetValue(fileOption),
        parseResult.GetValue(quoteArgument),
        parseResult.GetValue(bylineArgument))
        );
    

    Alt komutun quotes yaprak komutu olmadığından bir eylemi yoktur. read, addve delete, quotesaltında yaprak alt komutlardır ve her biri için SetAction çağrılır.

  5. add ve delete için eylemleri ekleyin.

    internal static void DeleteFromFile(FileInfo file, string[] searchTerms)
    {
        Console.WriteLine("Deleting from file");
    
        var lines = File.ReadLines(file.FullName).Where(line => searchTerms.All(s => !line.Contains(s)));
        File.WriteAllLines(file.FullName, lines);
    }
    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}");
    }
    

Tamamlanmış uygulama şöyle görünür:

using System.CommandLine;

namespace scl;

class Program
{
    static int Main(string[] args)
    {
        Option<FileInfo> fileOption = new("--file")
        {
            Description = "An option whose argument is parsed as a FileInfo",
            Required = true,
            DefaultValueFactory = result =>
            {
                if (result.Tokens.Count == 0)
                {
                    return new FileInfo("sampleQuotes.txt");

                }
                string filePath = result.Tokens.Single().Value;
                if (!File.Exists(filePath))
                {
                    result.AddError("File does not exist");
                    return null;
                }
                else
                {
                    return new FileInfo(filePath);
                }
            }
        };

        Option<int> delayOption = new("--delay")
        {
            Description = "Delay between lines, specified as milliseconds per character in a line.",
            DefaultValueFactory = parseResult => 42
        };
        Option<ConsoleColor> fgcolorOption = new("--fgcolor")
        {
            Description = "Foreground color of text displayed on the console.",
            DefaultValueFactory = parseResult => ConsoleColor.White
        };
        Option<bool> lightModeOption = new("--light-mode")
        {
            Description = "Background color of text displayed on the console: default is black, light mode is white."
        };

        Option<string[]> searchTermsOption = new("--search-terms")
        {
            Description = "Strings to search for when deleting entries.",
            Required = true,
            AllowMultipleArgumentsPerToken = true
        };
        Argument<string> quoteArgument = new("quote")
        {
            Description = "Text of quote."
        };
        Argument<string> bylineArgument = new("byline")
        {
            Description = "Byline of quote."
        };

        RootCommand rootCommand = new("Sample app for System.CommandLine");
        fileOption.Recursive = true;
        rootCommand.Options.Add(fileOption);

        Command quotesCommand = new("quotes", "Work with a file that contains quotes.");
        rootCommand.Subcommands.Add(quotesCommand);

        Command readCommand = new("read", "Read and display the file.")
        {
            delayOption,
            fgcolorOption,
            lightModeOption
        };
        quotesCommand.Subcommands.Add(readCommand);

        Command deleteCommand = new("delete", "Delete lines from the file.");
        deleteCommand.Options.Add(searchTermsOption);
        quotesCommand.Subcommands.Add(deleteCommand);

        Command addCommand = new("add", "Add an entry to the file.");
        addCommand.Arguments.Add(quoteArgument);
        addCommand.Arguments.Add(bylineArgument);
        addCommand.Aliases.Add("insert");
        quotesCommand.Subcommands.Add(addCommand);

        readCommand.SetAction(parseResult => ReadFile(
            parseResult.GetValue(fileOption),
            parseResult.GetValue(delayOption),
            parseResult.GetValue(fgcolorOption),
            parseResult.GetValue(lightModeOption)));

        deleteCommand.SetAction(parseResult => DeleteFromFile(
            parseResult.GetValue(fileOption),
            parseResult.GetValue(searchTermsOption)));

        addCommand.SetAction(parseResult => AddToFile(
            parseResult.GetValue(fileOption),
            parseResult.GetValue(quoteArgument),
            parseResult.GetValue(bylineArgument))
            );

        return rootCommand.Parse(args).Invoke();
    }

    internal static void ReadFile(FileInfo file, int delay, ConsoleColor fgColor, bool lightMode)
    {
        Console.BackgroundColor = lightMode ? ConsoleColor.White : ConsoleColor.Black;
        Console.ForegroundColor = fgColor;
        foreach (string line in File.ReadLines(file.FullName))
        {
            Console.WriteLine(line);
            Thread.Sleep(TimeSpan.FromMilliseconds(delay * line.Length));
        }
    }
    internal static void DeleteFromFile(FileInfo file, string[] searchTerms)
    {
        Console.WriteLine("Deleting from file");

        var lines = File.ReadLines(file.FullName).Where(line => searchTerms.All(s => !line.Contains(s)));
        File.WriteAllLines(file.FullName, lines);
    }
    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}");
    }
}

Projeyi derleyin ve aşağıdaki komutları deneyin.

--file komutuyla var olmayan bir dosyayı read gönderin ve özel durum ve yığın izlemesi yerine bir hata iletisi alırsınız:

scl quotes read --file nofile
File does not exist

Alt komut quotes çalıştırmayı deneyin ve sizi read, addveya deletekullanmaya 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.

addalt komutunu ç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 komut 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"

Uyarı

bin/debug/net9.0 klasöründe çalışıyorsanız, add ve delete komutlarındaki değişikliklerin bulunduğu dosyayı bu klasörde bulabilirsiniz. Proje klasöründeki dosyanın kopyası değişmeden kalır.

Sonraki adımlar

Bu öğreticide, System.CommandLinekullanan basit bir komut satırı uygulaması oluşturdunuz. Kitaplık hakkında daha fazla bilgi edinmek için bkz. System.CommandLine genel bakış.