Megosztás:


Oktatóanyag: Első lépések System.CommandLine

Ez az oktatóanyag bemutatja, hogyan hozhat létre .NET parancssori alkalmazást, amely a kódtáratSystem.CommandLine használja. Először hozzon létre egy egyszerű gyökérparancsot, amely egyetlen lehetőséggel rendelkezik. Ezután erre a bázisra fog építeni, és létrehoz egy összetettebb alkalmazást, amely több alparancsot és különböző beállításokat tartalmaz az egyes parancsokhoz.

Ebben az oktatóanyagban a következőket sajátíthatja el:

  • Parancsok, beállítások és argumentumok létrehozása.
  • Adja meg a beállítások alapértelmezett értékeit.
  • Beállítások és argumentumok hozzárendelése parancsokhoz.
  • Rendeljen rekurzívan egy beállítást a parancs alatt lévő összes alparancshoz.
  • Többszintű beágyazott alparancsokkal dolgozhat.
  • Aliasok létrehozása parancsokhoz és beállításokhoz.
  • Dolgozz string, string[], int, bool, FileInfo és enum beállítástípusokkal.
  • A parancsművelet kódjában lévő beállításértékek olvasása.
  • Egyéni kód használata elemzési és érvényesítési beállításokhoz.

Előfeltételek

Vagy

  • Visual Studio a .NET asztali fejlesztési munkaállomás telepítésével.

Az alkalmazás létrehozása

Hozzon létre egy "scl" nevű .NET 9-konzolalkalmazás-projektet.

  1. Hozzon létre egy scl nevű mappát a projekthez, majd nyisson meg egy parancssort az új mappában.

  2. Futtassa a következő parancsot:

    dotnet new console --framework net9.0
    

Telepítse a(z) System.CommandLine csomagot

  • Futtassa a következő parancsot:

    dotnet add package System.CommandLine
    

    Vagy a .NET 10+-ban:

    dotnet package add System.CommandLine
    

Az argumentumok elemzése

Cserélje le a Program.cs fájl tartalmát a következő kódra:

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.Errors.Count == 0 && 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);
        }
    }
}

Az előző kód:

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 Elemzi és ellenőrzi, hogy van-e megadva érték a --file beállításhoz. Ha igen, meghívja a ReadFile metódust az elemezett érték használatával, és visszaadja a kilépési kódot 0:
ParseResult parseResult = rootCommand.Parse(args);
if (parseResult.Errors.Count == 0 && parseResult.GetValue(fileOption) is FileInfo parsedFile)
{
    ReadFile(parsedFile);
    return 0;
}
  • Ha nincs megadva --fileérték, akkor kiírja az elérhető elemzési hibákat, és visszaadja a kilépési kódot 1:
foreach (ParseError parseError in parseResult.Errors)
{
    Console.Error.WriteLine(parseError.Message);
}
return 1;
  • A ReadFile metódus beolvassa a megadott fájlt, és megjeleníti annak tartalmát a konzolon:
static void ReadFile(FileInfo file)
{
    foreach (string line in File.ReadLines(file.FullName))
    {
        Console.WriteLine(line);
    }
}

Az alkalmazás tesztelése

A parancssori alkalmazások fejlesztése során az alábbi módszerek bármelyikét használhatja a teszteléshez:

  • Futtassa a dotnet build parancsot, majd nyisson meg egy parancssort a build kimeneti mappájában a végrehajtható fájl futtatásához:

    dotnet build
    cd bin/Debug/net9.0
    scl --file scl.runtimeconfig.json
    
  • Használja a dotnet run parancsot, és adja át a beállításértékeket az alkalmazásnak ahelyett, hogy a run parancsra tenné, ahogyan azt a -- példában látható:

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

(Ez az oktatóanyag feltételezi, hogy az első lehetőséget használja.)

Az alkalmazás futtatásakor megjelenik a beállítás által --file megadott fájl tartalma.

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

Ha azonban megpróbálja megjeleníteni a súgót a --help megadásával, nem nyomtat ki semmit a konzolra. Ennek az az oka, hogy az alkalmazás még nem kezeli azt a forgatókönyvet, amelyben --file nincs megadva, és nincsenek elemzési hibák.

Az argumentumok elemzése és a ParseResult meghívása

System.CommandLine Lehetővé teszi egy adott szimbólum (parancs, irányelv vagy beállítás) sikeres elemzésekor meghívott művelet megadását. A művelet egy olyan delegált típus, amely egy ParseResult paramétert fogad, és egy int kilépési kódot ad vissza. (Aszinkron műveletek is elérhetők). A metódus visszaadja a ParseResult.Invoke(InvocationConfiguration) kilépési kódot, és annak jelzésére használható, hogy a parancs végrehajtása sikeresen megtörtént-e.

Cserélje le a Program.cs fájl tartalmát a következő kódra:

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

Az előző kód:

  • Megadja, hogy ReadFile a rendszer ezt a metódust hívja meg a gyökérparancs meghívásakor:

    rootCommand.SetAction(parseResult =>
    {
        FileInfo parsedFile = parseResult.GetValue(fileOption);
        ReadFile(parsedFile);
        return 0;
    });
    
  • args Elemzi és meghívja az eredményt:

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

Az alkalmazás futtatásakor megjelenik a beállítás által --file megadott fájl tartalma.

Ha azt kéri, hogy jelenítse meg scl --help-vel a súgót, akkor a következő kimenet jelenik meg:

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 console

RootCommand alapértelmezés szerint a Súgó,a Verzió és a Javaslat direktíva lehetőséget adja meg. A ParseResult.Invoke(InvocationConfiguration) metódus feladata az elemzett szimbólum műveletének invokálása. Ez lehet a parancshoz explicit módon definiált művelet vagy a hozzá System.CommandLinetartozó System.CommandLine.Help.HelpOption súgóművelet.

Továbbá, amikor a Invoke metódus bármilyen elemzési hibát észlel, azt a standard hiba folyamra írja ki, a helpet a standard kimenetre nyomtatja, és 1-ként tér vissza kilépési kódként.

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

Alparancs és beállítások hozzáadása

Ebben a szakaszban ön a következőket fogja megtenni:

  • Hozzon létre további lehetőségeket.
  • Hozzon létre egy alparancsot.
  • Rendelje hozzá az új beállításokat az új alparancshoz.

Az új beállítások lehetővé teszik, hogy a végfelhasználó konfigurálja az előtér- és háttérszöveg-színeket, valamint az olvasási sebességet. Ezek a funkciók a Teleprompter konzolalkalmazás oktatóanyagából származó idézetek gyűjteményének olvasására szolgálnak.

  1. Másolja a sampleQuotes.txt fájlt a dotnet-minták tárházából a projektkönyvtárba.

    (A fájlok letöltésével kapcsolatos információkért tekintse meg a Minták és oktatóanyagok című témakör utasításait.)

  2. Nyissa meg a projektfájlt, és adjon hozzá egy <ItemGroup> elemet a záró </Project> címke előtt:

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

    A korrektúra hozzáadásakor a szövegfájl a kimeneti mappába lesz másolva az alkalmazás létrehozásakor. Így amikor futtatja a végrehajtható fájlt abban a mappában, név szerint érheti el a fájlt anélkül, hogy meg kell adnia egy mappa elérési útját.

  3. A Program.cs a lehetőséget létrehozó --file kód után hozzon létre beállításokat az olvasási sebesség és a szövegszínek szabályozásához:

    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. A gyökérparancsot létrehozó sor után törölje azt a kódot, amely hozzáadja a --file lehetőséget. Azért távolítja el itt, mert hozzá fogja adni egy új alparancshoz.

  5. A gyökérparancsot létrehozó sor után hozzon létre egy read alparancsot. Adja hozzá a beállításokat ehhez az alparancshoz (a gyűjtemény inicializáló szintaxisát használva a Options tulajdonság helyett), és adja hozzá az alparancsot a gyökérparancshoz.

    Command readCommand = new("read", "Read and display the file.")
    {
        fileOption,
        delayOption,
        fgcolorOption,
        lightModeOption
    };
    rootCommand.Subcommands.Add(readCommand);
    
  6. Cserélje le a SetAction kódot az új alparancs következő SetAction kódjával:

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

    Már nem hívja meg SetAction a gyökérparancsot, mert a gyökérparancsnak már nincs szüksége műveletre. Ha egy parancshoz alparancsok tartoznak, általában meg kell adnia az egyik alparancsot egy parancssori alkalmazás meghívásakor.

  7. Cserélje le a ReadFile műveletmetódust a következő kódra:

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

Az alkalmazás így néz ki:

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

Az új alparancs tesztelése

Ha most az alparancs megadása nélkül próbálja futtatni az alkalmazást, hibaüzenet jelenik meg, majd egy súgóüzenet, amely megadja az elérhető alparancsot.

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.

Az alparancs read súgószövege azt mutatja, hogy négy lehetőség érhető el. Az enumerálás érvényes értékeit jeleníti meg.

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

Futtassa az alparancsot read , amely csak a --file beállítást adja meg, és a másik három beállítás alapértelmezett értékeit kapja meg.

scl read --file sampleQuotes.txt

A karakterenkénti 42 ezredmásodperces alapértelmezett késleltetés lassú olvasási sebességet okoz. Felgyorsíthatja a sebességet, ha alacsonyabb számra állítja --delay be.

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

Használhatja --fgcolor és --light-mode beállíthatja a szövegszíneket:

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

Ha érvénytelen értéket --delayad meg, hibaüzenet jelenik meg:

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

Ha érvénytelen értéket --filead meg, kivételt kap:

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''

Alparancsok és egyéni ellenőrzés hozzáadása

Ez a szakasz létrehozza az alkalmazás végleges verzióját. Ha elkészült, az alkalmazás a következő parancsokkal és beállításokkal rendelkezik:

Command Beállítások Arguments
Gyökérparancs --file (rekurzív)
quotes
read \, \, \
add quote és byline
delete --search-terms

( Rekurzív beállítás érhető el a hozzá rendelt parancshoz, és rekurzív módon az összes alparancshoz.)

Az alábbi példa parancssori bemenete meghívja az egyes elérhető parancsokat a beállításaival és argumentumaival:

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. A Program.cs cserélje le a lehetőséget létrehozó --file kódot a következő kódra:

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

    Ez a kód egyéni elemzést, ellenőrzést és hibakezelést biztosít ArgumentResult .

    Kód nélkül a hiányzó fájlokról kivétel és veremkövetés formájában történik jelentés. Ezzel a kóddal csak a megadott hibaüzenet jelenik meg.

    Ez a kód egy alapértelmezett értéket is megad, ezért egyéni elemzési módszerre állítja be Option<T>.DefaultValueFactory .

  2. A létrehozott lightModeOptionkód után adjon hozzá beállításokat és argumentumokat a add parancsokhoz delete :

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

    A AllowMultipleArgumentsPerToken beállítás lehetővé teszi, hogy kihagyja a --search-terms beállítás nevét, amikor a lista elemeit az első után adja meg. A következő parancssori bevitel példák egyenértékűek:

    scl quotes delete --search-terms David "You can do"
    scl quotes delete --search-terms David --search-terms "You can do"
    
  3. Cserélje le a gyökérparancsot létrehozó kódot és a read parancsot a következő kódra:

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

    Ez a kód a következő módosításokat hajtja végre:

    • Eltávolítja a --file lehetőséget a read parancsból.

    • Rekurzív beállításként adja hozzá a --file lehetőséget a gyökérparancshoz.

    • Létrehoz egy quotes parancsot, és hozzáadja a gyökérparancshoz.

    • A read parancsot a quotes parancshoz adja hozzá a gyökérparancs helyett.

    • Létrehozza add és delete hozzáadja őket a quotes parancshoz.

    Az eredmény a következő parancshierarchia:

    Gyökérparancs └──quotes └──read └──add └────delete

    Az alkalmazás most implementálja az ajánlott mintát, amelyben a szülőparancs (quotes) meghatároz egy területet vagy csoportot, és a gyermekparancsok (read, add, delete) műveletek.

    A rendszer rekurzív beállításokat alkalmaz a parancsra, és rekurzívan az alparancsokra. Mivel --file a gyökérparancson van, automatikusan elérhetővé válik az alkalmazás összes alparancsában.

  4. SetAction A kód után adjon hozzá új SetAction kódot az új alparancsokhoz:

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

    Az alparancsnak quotes nincs művelete, mert nem végső parancs. Az read, add és delete parancsok levélszerű parancsok az quotes alatt, és SetAction hívása történik meg mindegyikhez.

  5. Adja hozzá a műveleteket add és delete számára.

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

A kész alkalmazás a következőképpen néz ki:

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

Hozza létre a projektet, majd próbálkozzon az alábbi parancsokkal.

Küldjön be egy nem létező fájlt --file a paranccsal, és a kivétel és a read veremkövetés helyett hibaüzenet jelenik meg:

scl quotes read --file nofile
File does not exist

Ha alparancsot quotespróbál futtatni, megjelenik egy üzenet, amely arra utasítja, hogy használja read, addvagy 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.

Futtassa az alparancsot add, majd tekintse meg a szövegfájl végét a hozzáadott szöveg megtekintéséhez:

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

Futtassa az alparancsot delete a fájl elejéről vett keresési sztringekkel, majd nézze meg a szövegfájl elejét, hogy lássa, hol történt a szöveg eltávolítása.

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

Megjegyzés

A kimeneti mappában lévő fájl a add és delete parancsok változtatásait tükrözi. A projektmappában lévő fájl másolata változatlan marad.

Következő lépések

Ebben az oktatóanyagban létrehoztál egy egyszerű parancssori alkalmazást, amely a következőt használja System.CommandLine: A tárról további információt az áttekintésben találSystem.CommandLine. A tabulátorkiegészítési képességek engedélyezéséhez tekintse meg a Tabulátorkiegészítés című témakört System.CommandLine.