Bagikan melalui


Tutorial: Mulailah dengan System.CommandLine

Penting

System.CommandLine saat ini dalam PRATINJAU, dan dokumentasi ini untuk versi 2.0 beta 4. Beberapa informasi terkait produk prarilis yang dapat diubah secara signifikan sebelum dirilis. Microsoft tidak memberikan jaminan, tersirat maupun tersurat, sehubungan dengan informasi yang diberikan di sini.

Tutorial ini menunjukkan cara membuat aplikasi baris perintah .NET yang menggunakan System.CommandLine pustaka . Anda akan mulai dengan membuat perintah akar sederhana yang memiliki satu opsi. Kemudian Anda akan menambahkan ke basis tersebut, membuat aplikasi yang lebih kompleks yang berisi beberapa sub perintah dan opsi yang berbeda untuk setiap perintah.

Dalam tutorial ini, Anda akan mempelajari cara:

  • Buat perintah, opsi, dan argumen tersembunyi.
  • Tentukan nilai default untuk opsi.
  • Tetapkan opsi dan argumen ke perintah.
  • Tetapkan opsi secara rekursif ke semua sub perintah di bawah perintah.
  • Bekerja dengan beberapa tingkat sub perintah berlapis.
  • Buat alias untuk perintah dan opsi.
  • Bekerja dengan string, string[], int, bool, FileInfo dan jenis opsi enum.
  • Ikat nilai opsi ke kode handler perintah.
  • Gunakan kode kustom untuk memilah dan memvalidasi opsi.

Prasyarat

Atau

Membuat aplikasi

Buat proyek aplikasi konsol .NET 6 bernama "scl".

  1. Buat folder bernama scl untuk proyek, lalu buka prompt perintah di folder baru.

  2. Jalankan perintah berikut:

    dotnet new console --framework net6.0
    

Pasang paket System.CommandLine

  • Jalankan perintah berikut:

    dotnet add package System.CommandLine --prerelease
    

    Opsi --prerelease ini diperlukan karena pustaka masih dalam versi beta.

  1. Ganti konten Program.cs dengan kode berikut:

    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));
        }
    }
    

Kode sebelumnya:

  • Membuat opsi bernama --file jenis FileInfo dan menetapkannya ke perintah akar:

    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);
    
  • Menentukan bahwa ReadFile adalah metode yang akan dipanggil ketika perintah akar dipanggil:

    rootCommand.SetHandler((file) => 
        { 
            ReadFile(file!); 
        },
        fileOption);
    
  • Menampilkan isi file yang ditentukan ketika perintah akar dipanggil:

    static void ReadFile(FileInfo file)
    {
        File.ReadLines(file.FullName).ToList()
            .ForEach(line => Console.WriteLine(line));
    }
    

Menguji aplikasi

Anda dapat menggunakan salah satu cara berikut untuk menguji saat mengembangkan aplikasi baris perintah:

  • Jalankan dotnet build perintah, lalu buka perintah di folder scl/bin/Debug/net6.0 untuk menjalankan executable:

    dotnet build
    cd bin/Debug/net6.0
    scl --file scl.runtimeconfig.json
    
  • Gunakan dotnet run dan teruskan nilai opsi ke aplikasi alih-alih ke run perintah dengan menyertakannya setelah --, seperti dalam contoh berikut:

    dotnet run -- --file scl.runtimeconfig.json
    

    Dalam Pratinjau .NET 7.0.100 SDK, Anda dapat menggunakan commandLineArgs dari file launchSettings.json dengan menjalankan perintah dotnet run --launch-profile <profilename>.

  • Terbitkan proyek ke folder, buka perintah ke folder tersebut, dan jalankan executable:

    dotnet publish -o publish
    cd ./publish
    scl --file scl.runtimeconfig.json
    
  • Di Visual Studio 2022, pilih Properti DebugDebug> dari menu, dan masukkan opsi dan argumen dalam kotak Argumen baris perintah. Contohnya:

    Argumen baris perintah di Visual Studio 2022

    Kemudian jalankan aplikasi, misalnya dengan menekan Ctrl+F5.

Tutorial ini mengasumsikan Anda menggunakan opsi pertama dari opsi ini.

Saat Anda menjalankan aplikasi, aplikasi akan menampilkan konten file yang ditentukan oleh --file opsi.

{
  "runtimeOptions": {
    "tfm": "net6.0",
    "framework": {
      "name": "Microsoft.NETCore.App",
      "version": "6.0.0"
    }
  }
}

Output bantuan

System.CommandLine secara otomatis menyediakan output bantuan:

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

Output versi

System.CommandLine secara otomatis menyediakan output versi:

scl --version
1.0.0

Menambahkan sub perintah dan opsi

Di bagian ini, Anda:

  • Buat opsi lainnya.
  • Buat sub perintah.
  • Tetapkan opsi baru ke sub perintah baru.

Opsi baru akan memungkinkan Anda mengonfigurasi warna teks latar depan dan latar belakang serta kecepatan baca. Fitur-fitur ini akan digunakan untuk membaca kumpulan tanda kutip yang berasal dari tutorial aplikasi konsol Teleprompter.

  1. Salin file sampleQuotes.txt dari repositori GitHub untuk sampel ini ke direktori proyek Anda. Untuk informasi tentang cara mengunduh file, lihat instruksi dalam Sampel dan Tutorial.

  2. Buka file proyek dan tambahkan <ItemGroup> elemen tepat sebelum tag penutup </Project>:

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

    Menambahkan markup ini menyebabkan file teks disalin ke folder bin/debug/net6.0 saat Anda membuat aplikasi. Jadi, ketika Anda menjalankan executable di folder tersebut, Anda dapat mengakses file berdasarkan nama tanpa menentukan jalur folder.

  3. Di Program.cs, setelah kode yang membuat --file opsi, buat opsi untuk mengontrol kecepatan pembacaan dan warna teks:

    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.");
    
  4. Setelah baris yang membuat perintah root, hapus baris yang menambahkan opsi ke --file dalamnya. Anda menghapusnya di sini karena Anda akan menambahkannya ke sub perintah baru.

    var rootCommand = new RootCommand("Sample app for System.CommandLine");
    //rootCommand.AddOption(fileOption);
    
  5. Setelah baris yang membuat perintah akar, buat read sub perintah. Tambahkan opsi ke sub perintah ini, dan tambahkan sub perintah ke perintah akar.

    var readCommand = new Command("read", "Read and display the file.")
        {
            fileOption,
            delayOption,
            fgcolorOption,
            lightModeOption
        };
    rootCommand.AddCommand(readCommand);
    
  6. Ganti SetHandler kode dengan kode berikut SetHandler untuk sub perintah baru:

    readCommand.SetHandler(async (file, delay, fgcolor, lightMode) =>
        {
            await ReadFile(file!, delay, fgcolor, lightMode);
        },
        fileOption, delayOption, fgcolorOption, lightModeOption);
    

    Anda tidak lagi memanggil SetHandler perintah root karena perintah root tidak lagi memerlukan handler. Saat perintah memiliki sub perintah, Anda biasanya harus menentukan salah satu sub perintah saat memanggil aplikasi baris perintah.

  7. Ganti ReadFile metode handler dengan kode berikut:

    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);
        };
    }
    

Aplikasi sekarang terlihat seperti ini:

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);
        };
    }
}

Menguji sub perintah baru

Sekarang jika Anda mencoba menjalankan aplikasi tanpa menentukan subperinci, Anda mendapatkan pesan kesalahan diikuti oleh pesan bantuan yang menentukan subperinci yang tersedia.

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.

Teks bantuan untuk sub perintah read menunjukkan bahwa empat opsi tersedia. Ini menunjukkan nilai yang valid untuk enum.

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

Jalankan subperintah read yang hanya --file menentukan opsi, dan Anda mendapatkan nilai default untuk tiga opsi lainnya.

scl read --file sampleQuotes.txt

Penundaan default 42 milidetik per karakter menyebabkan kecepatan baca-baca yang lambat. Anda dapat mempercepatnya dengan mengatur --delay ke angka yang lebih rendah.

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

Anda dapat menggunakan --fgcolor dan --light-mode untuk mengatur warna teks:

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

Berikan nilai yang tidak valid untuk --delay dan Anda mendapatkan pesan kesalahan:

scl read --file sampleQuotes.txt --delay forty-two
Cannot parse argument 'forty-two' for option '--int' as expected type 'System.Int32'.

Berikan nilai yang tidak valid untuk --file dan Anda mendapatkan pengecualian:

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

Menambahkan sub perintah dan validasi kustom

Bagian ini membuat versi akhir aplikasi. Setelah selesai, aplikasi akan memiliki perintah dan opsi berikut:

  • perintah root dengan opsi global* bernama --file
    • perintah quotes
      • read perintah dengan opsi bernama --delay, --fgcolor, dan --light-mode
      • add perintah dengan argumen bernama quote dan byline
      • delete perintah dengan opsi bernama --search-terms

* Opsi global tersedia untuk perintah yang ditetapkan dan secara rekursif ke semua sub perintahnya.

Berikut adalah contoh input baris perintah yang memanggil setiap perintah yang tersedia dengan opsi dan argumennya:

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. Di Program.cs, ganti kode yang membuat --file opsi dengan kode berikut:

    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);
            }
        });
    

    Kode ini menggunakan ParseArgument<T> untuk menyediakan penguraian kustom, validasi, dan penanganan kesalahan.

    Tanpa kode ini, file yang hilang dilaporkan dengan pengecualian dan pelacakan tumpukan. Dengan kode ini hanya pesan kesalahan yang ditentukan yang ditampilkan.

    Kode ini juga menentukan nilai default, itulah sebabnya diatur isDefault ke true. Jika Anda tidak mengatur isDefault ke true, parseArgument delegasi tidak dipanggil ketika tidak ada input yang disediakan untuk --file.

  2. Setelah kode yang membuat lightModeOption, tambahkan opsi dan argumen untuk add perintah dan delete :

    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.");
    

    Pengaturan memungkinkan AllowMultipleArgumentsPerToken Anda menghilangkan --search-terms nama opsi saat menentukan elemen dalam daftar setelah yang pertama. Ini membuat contoh input baris perintah berikut setara:

    scl quotes delete --search-terms David "You can do"
    scl quotes delete --search-terms David --search-terms "You can do"
    
  3. Ganti kode yang membuat perintah root dan read perintah dengan kode berikut:

    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);
    

    Pembaruan kode ini membuat perubahan berikut:

    • Menghapus --file opsi dari read perintah.

    • Menambahkan --file opsi sebagai opsi global ke perintah root.

    • Membuat quotes perintah dan menambahkannya ke perintah root.

    • Menambahkan read perintah ke quotes perintah alih-alih ke perintah akar.

    • Membuat add dan delete memerintahkan dan menambahkannya ke quotes perintah.

    Hasilnya adalah hierarki perintah berikut:

    • Perintah akar
      • quotes
        • read
        • add
        • delete

    Aplikasi sekarang menerapkan pola yang direkomendasikan di mana perintah induk (quotes) menentukan area atau grup, dan perintah turunannya (read, add, delete) adalah tindakan.

    Opsi global diterapkan ke perintah dan secara rekursif ke sub perintah. Karena --file ada pada perintah root, perintah akan tersedia secara otomatis di semua sub perintah aplikasi.

  4. Setelah SetHandler kode, tambahkan kode baru SetHandler untuk sub perintah baru:

    deleteCommand.SetHandler((file, searchTerms) =>
        {
            DeleteFromFile(file!, searchTerms);
        },
        fileOption, searchTermsOption);
    
    addCommand.SetHandler((file, quote, byline) =>
        {
            AddToFile(file!, quote, byline);
        },
        fileOption, quoteArgument, bylineArgument);
    

    Sub perintah quotes tidak memiliki handler karena bukan perintah daun. Sub perintah read, add, dan delete merupakan perintah daun di bawah quotes, dan SetHandler dipanggil untuk masing-masing perintah.

  5. Tambahkan handler untuk add dan delete.

    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();
    }
    

Aplikasi yang sudah selesai terlihat seperti ini:

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();
    }
}

Buat proyek, lalu coba perintah berikut.

Kirimkan file yang tidak ada ke --file dengan read perintah, dan Anda mendapatkan pesan kesalahan alih-alih pengecualian dan pelacakan tumpukan:

scl quotes read --file nofile
File does not exist

Cobalah untuk menjalankan subperintah quotes dan Anda mendapatkan pesan yang mengarahkan Anda untuk menggunakan read, add, atau delete:

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.

Jalankan subperintah add, lalu lihat akhir file teks untuk melihat teks yang ditambahkan:

scl quotes add "Hello world!" "Nancy Davolio"

Jalankan subperintah delete dengan string pencarian dari awal file, lalu lihat awal file teks untuk melihat di mana teks dihapus:

scl quotes delete --search-terms David "You can do" Antoine "Perfection is achieved"

Catatan

Jika Anda menjalankan di folder bin/debug/net6.0, folder tersebut adalah tempat Anda akan menemukan file dengan perubahan dari add perintah dan delete. Salinan file dalam folder proyek tetap tidak berubah.

Langkah berikutnya

Dalam tutorial ini, Anda membuat aplikasi baris perintah sederhana yang menggunakan System.CommandLine. Untuk mempelajari lebih lanjut tentang perpustakaan, lihat System.CommandLine gambaran umum .