Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
W tym samouczku pokazano, jak utworzyć aplikację wiersza polecenia platformy .NET korzystającą z biblioteki System.CommandLine. Zaczniesz od utworzenia prostego polecenia głównego, które ma jedną opcję. Następnie utworzysz na tej podstawie bardziej złożoną aplikację zawierającą wiele poleceń podrzędnych i różne opcje dla każdego polecenia.
Z tego samouczka dowiesz się, jak wykonywać następujące działania:
- Utwórz polecenia, opcje i argumenty.
- Określ wartości domyślne opcji.
- Przypisz opcje i argumenty do poleceń.
- Przypisz opcję rekursywnie do wszystkich podpoleceń w poleceniu.
- Pracować z wieloma poziomami zagnieżdżonych poleceń podrzędnych.
- Utwórz aliasy dla poleceń i opcji.
- Praca z typami
string,string[],int,bool,FileInfoi typami wyliczeniowymi. - Odczytywanie wartości opcji w kodzie działania polecenia.
- Użyj niestandardowego kodu do analizowania i sprawdzania poprawności opcji.
Wymagania wstępne
- Najnowsza wersja zestawu .NET SDK
- Edytor programu Visual Studio Code
- Zestaw deweloperski C#
lub
- programu Visual Studio 2022 z zainstalowanym pakietem do tworzenia aplikacji klasycznych .NET .
Tworzenie aplikacji
Utwórz projekt aplikacji konsolowej platformy .NET 9 o nazwie "scl".
Utwórz folder o nazwie scl dla projektu, a następnie otwórz wiersz polecenia w nowym folderze.
Uruchom następujące polecenie:
dotnet new console --framework net9.0
Instalowanie pakietu System.CommandLine
Uruchom następujące polecenie:
dotnet add package System.CommandLine --prereleaseLub w .NET 10+:
dotnet package add System.CommandLine --prereleaseOpcja
--prereleasejest niezbędna, ponieważ biblioteka jest nadal dostępna w wersji beta.
Analizowanie argumentów
Zastąp zawartość pliku Program.cs następującym kodem:
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); } } }
Poprzedni kod:
- Tworzy opcję o nazwie
--filetypu FileInfo i dodaje ją do głównego polecenia:
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);
- Analizuje
argsi sprawdza, czy dla opcji--filepodano jakąkolwiek wartość. Jeśli tak, wywołuje metodęReadFileprzy użyciu przeanalizowanej wartości i zwraca0kod zakończenia:
ParseResult parseResult = rootCommand.Parse(args);
if (parseResult.Errors.Count == 0 && parseResult.GetValue(fileOption) is FileInfo parsedFile)
{
ReadFile(parsedFile);
return 0;
}
- Jeśli dla parametru nie podano
--fileżadnej wartości , wyświetla dostępne błędy analizy i zwraca1kod zakończenia:
foreach (ParseError parseError in parseResult.Errors)
{
Console.Error.WriteLine(parseError.Message);
}
return 1;
- Metoda
ReadFileodczytuje określony plik i wyświetla jego zawartość w konsoli:
static void ReadFile(FileInfo file)
{
foreach (string line in File.ReadLines(file.FullName))
{
Console.WriteLine(line);
}
}
Testowanie aplikacji
Możesz użyć dowolnego z następujących sposobów testowania podczas tworzenia aplikacji wiersza polecenia:
dotnet buildUruchom polecenie, a następnie otwórz wiersz polecenia w folderze scl/bin/Debug/net9.0, aby uruchomić plik wykonywalny:dotnet build cd bin/Debug/net9.0 scl --file scl.runtimeconfig.jsonUżyj
dotnet runi przekaż wartości opcji do aplikacji zamiast poleceniarun, dołączając je po--, jak w poniższym przykładzie:dotnet run -- --file bin/Debug/net9.0/scl.runtimeconfig.json
W tym samouczku założono, że używasz pierwszej z tych opcji.
Po uruchomieniu aplikacji wyświetla zawartość pliku określonego przez opcję --file.
{
"runtimeOptions": {
"tfm": "net9.0",
"framework": {
"name": "Microsoft.NETCore.App",
"version": "9.0.0"
}
}
}
Ale co się stanie, jeśli poprosisz go o wyświetlenie pomocy, podając --help? Nic nie jest wyświetlane na konsoli, ponieważ aplikacja nie obsługuje jeszcze scenariusza, w którym --file nie zostało dostarczone i nie ma żadnych błędów parsowania.
Przeanalizuj argumenty i wywołaj element ParseResult
System.CommandLine Umożliwia określenie akcji wywoływanej, gdy dany symbol (polecenie, dyrektywa lub opcja) jest analizowany pomyślnie. Akcja to delegat, który przyjmuje System.CommandLine.ParseResult parametr i zwraca int kod zakończenia ( dostępne są również akcje asynchroniczne). Kod zakończenia jest zwracany przez metodę System.CommandLine.Parsing.ParseResult.Invoke i może służyć do wskazania, czy polecenie zostało wykonane pomyślnie, czy nie.
Zastąp zawartość pliku Program.cs następującym kodem:
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); } } }
Poprzedni kod:
Określa, że
ReadFilejest to metoda, która będzie wywoływana po wywołaniu głównego polecenia:rootCommand.SetAction(parseResult => { FileInfo parsedFile = parseResult.GetValue(fileOption); ReadFile(parsedFile); return 0; });Analizuje element
argsi wywołuje wynik:ParseResult parseResult = rootCommand.Parse(args); return parseResult.Invoke();
Po uruchomieniu aplikacji wyświetla zawartość pliku określonego przez opcję --file.
Co się stanie, jeśli poprosisz go o wyświetlenie pomocy, podając --help?
scl --help
Zostanie wypisany następujący wynik:
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
RootCommand domyślnie udostępnia opcję Pomoc, opcję wersji i dyrektywę Suggest. Metoda ParseResult.Invoke(InvocationConfiguration) jest odpowiedzialna za wywołanie akcji przeanalizowanego symbolu. Może to być akcja jawnie zdefiniowana dla polecenia lub akcja pomocy zdefiniowana przez System.CommandLine dla System.CommandLine.Help.HelpOption. Ponadto, gdy wykryje błędy analizy, wyświetla je do standardowego błędu, drukuje pomoc w standardowych danych wyjściowych i zwraca 1 jako kod zakończenia:
scl --invalid bla
Unrecognized command or argument '--invalid'.
Unrecognized command or argument 'bla'.
Dodawanie podpolecenia i opcji
W tej sekcji Ty:
- Utwórz więcej opcji.
- Utwórz podpolecenie.
- Przypisz nowe opcje do nowego podpolecenia.
Nowe opcje umożliwiają skonfigurowanie kolorów tekstu pierwszego planu i tła oraz szybkości odczytu. Te funkcjonalności będą używane do odczytywania kolekcji cytatów, które pochodzą z samouczka aplikacji konsolowej Teleprompter .
Skopiuj plik sampleQuotes.txt z repozytorium GitHub dla tego przykładu do katalogu projektu. Aby uzyskać informacje na temat pobierania plików, zobacz instrukcje w Przykłady i samouczki.
Otwórz plik projektu i dodaj element
<ItemGroup>tuż przed tagiem zamykającym</Project>:<ItemGroup> <Content Include="sampleQuotes.txt"> <CopyToOutputDirectory>Always</CopyToOutputDirectory> </Content> </ItemGroup>Dodanie tego znacznika powoduje skopiowanie pliku tekstowego do folderu bin/debug/net9.0 podczas kompilowania aplikacji. Dlatego po uruchomieniu pliku wykonywalnego w tym folderze można uzyskać dostęp do pliku według nazwy bez określania ścieżki folderu.
W Program.cspo kodzie tworzącym opcję
--fileutwórz opcje kontrolowania szybkości odczytu i kolorów tekstu: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." };Po wierszu, który tworzy polecenie główne, usuń kod, który dodaje opcję
--filedo niego. Usuwasz go tutaj, ponieważ dodasz go do nowego podpolecenia.Po wierszu, który tworzy główne polecenie, utwórz podpolecenie
read. Dodaj opcje do tego podpolecenia (przy użyciu składni inicjatora kolekcji zamiast właściwościOptions) i dodaj podpolecenie do głównego polecenia.Command readCommand = new("read", "Read and display the file.") { fileOption, delayOption, fgcolorOption, lightModeOption }; rootCommand.Subcommands.Add(readCommand);Zastąp kod
SetActionnastępującym kodemSetActiondla nowego podpolecenia:readCommand.SetAction(parseResult => ReadFile( parseResult.GetValue(fileOption), parseResult.GetValue(delayOption), parseResult.GetValue(fgcolorOption), parseResult.GetValue(lightModeOption)));Nie wywołujesz
SetActionjuż polecenia głównego, ponieważ polecenie główne nie wymaga już akcji. Gdy polecenie ma podpolecenia, zazwyczaj należy określić jedno z podpolecenia podczas wywoływania aplikacji wiersza polecenia.Zastąp metodę
ReadFileakcji następującym kodem: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)); } }
Aplikacja wygląda teraz następująco:
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));
}
}
}
Testowanie nowego podpolecenia
Teraz, jeśli spróbujesz uruchomić aplikację bez określenia podpolecenia, zostanie wyświetlony komunikat o błędzie z komunikatem pomocy określającym dostępne podpolecenia.
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.
Tekst pomocy dla podpolecenia read wskazuje, że dostępne są cztery opcje. Wyświetla prawidłowe wartości enumeracji.
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
Uruchom polecenie podrzędne read określając tylko opcję --file i uzyskasz wartości domyślne pozostałych trzech opcji.
scl read --file sampleQuotes.txt
Domyślne opóźnienie 42 milisekund na znak powoduje spowolnienie szybkości odczytu. Możesz go przyspieszyć, ustawiając --delay na mniejszą liczbę.
scl read --file sampleQuotes.txt --delay 0
Aby ustawić kolory tekstu, możesz użyć --fgcolor i --light-mode:
scl read --file sampleQuotes.txt --fgcolor red --light-mode
Podaj nieprawidłową wartość dla --delay i zostanie wyświetlony komunikat o błędzie:
scl read --file sampleQuotes.txt --delay forty-two
Cannot parse argument 'forty-two' for option '--int' as expected type 'System.Int32'.
Podaj nieprawidłową wartość dla --file i otrzymasz wyjątek:
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''
Dodawanie podpoleceń i walidacji niestandardowych
W tej sekcji zostanie utworzona ostateczna wersja aplikacji. Po zakończeniu aplikacja będzie mieć następujące polecenia i opcje:
- polecenie główne z opcją rekursywną* o nazwie
--file- polecenie
quotes-
readpolecenie z opcjami o nazwie--delay,--fgcolori--light-mode -
addpolecenie z argumentami o nazwachquoteibyline -
deletekomenda z opcją o nazwie--search-terms
-
- polecenie
* Opcja rekursywna jest dostępna dla polecenia, do którego jest przypisana, i rekursywnie do wszystkich jego podpoleceń.
Oto przykładowe dane wejściowe wiersza polecenia, które wywołują każde z dostępnych poleceń z jego opcjami i argumentami:
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"
W Program.cszastąp kod, który tworzy opcję
--filenastępującym kodem: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); } } };Ten kod używa
System.CommandLine.Parsing.ArgumentResultw celu zapewnienia niestandardowej analizy, walidacji i obsługi błędów.Bez tego kodu brakujące pliki są raportowane przy pomocy wyjątków i śladu stosu. Po wyświetleniu tego kodu zostanie wyświetlony tylko określony komunikat o błędzie.
Ten kod określa również wartość domyślną, dlatego ustawia
DefaultValueFactoryna niestandardową metodę analizowania.Po kodzie tworzącym
lightModeOptiondodaj opcje i argumenty dla poleceńaddidelete: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." };Ustawienie
xref:System.CommandLine.Option.AllowMultipleArgumentsPerTokenpozwala pominąć nazwę opcji--search-termspodczas określania elementów na liście po pierwszym. Przykłady danych wejściowych wiersza polecenia, które są równoważne, to:scl quotes delete --search-terms David "You can do" scl quotes delete --search-terms David --search-terms "You can do"Zastąp kod, który tworzy polecenie główne i polecenie
readnastępującym kodem: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);Ten kod wprowadza następujące zmiany:
Usuwa opcję
--filez poleceniaread.Dodaje opcję
--filejako opcję rekursywną do polecenia głównego.Tworzy polecenie
quotesi dodaje je do głównego polecenia.Dodaje polecenie
readdo poleceniaquoteszamiast do polecenia głównego.Tworzy polecenia
addideletei dodaje je do poleceniaquotes.
Wynikiem jest następująca hierarchia poleceń:
- Polecenie główne
quotesreadadddelete
Aplikacja implementuje teraz zalecany wzorzec, w którym polecenie nadrzędne (
quotes) określa obszar lub grupę, a jego polecenia podrzędne (read,add,delete) są akcjami.Opcje cykliczne są stosowane do polecenia i cyklicznie do podpolecenia. Ponieważ
--filejest w poleceniu głównym, będzie on automatycznie dostępny we wszystkich podpoleceniach aplikacji.Po kodzie
SetActiondodaj nowy kodSetActiondla nowych poleceń podrzędnych:deleteCommand.SetAction(parseResult => DeleteFromFile( parseResult.GetValue(fileOption), parseResult.GetValue(searchTermsOption))); addCommand.SetAction(parseResult => AddToFile( parseResult.GetValue(fileOption), parseResult.GetValue(quoteArgument), parseResult.GetValue(bylineArgument)) );Podpolecenie
quotesnie ma akcji, ponieważ nie jest to polecenie końcowe. Podpoleceniaread,addideletesą poleceniami końcowymi wquotes, aSetActionjest wywoływane dla każdego z nich.Dodaj akcje dla
addidelete.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}"); }
Zakończona aplikacja wygląda następująco:
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}");
}
}
Skompiluj projekt, a następnie spróbuj wykonać następujące polecenia.
Prześlij nieistniejący plik do --file przy użyciu polecenia read, a zamiast wyjątku i śledzenia stosu otrzymasz komunikat o błędzie:
scl quotes read --file nofile
File does not exist
Spróbuj uruchomić polecenie podrzędne quotes i zostanie wyświetlony komunikat kierujący cię do używania read, addlub 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.
Uruchom polecenie podrzędne add, a następnie przyjrzyj się końcu pliku tekstowego, aby zobaczyć dodany tekst:
scl quotes add "Hello world!" "Nancy Davolio"
Uruchom polecenie podrzędne delete z ciągami wyszukiwania od początku pliku, a następnie przyjrzyj się początku pliku tekstowego, aby zobaczyć, gdzie został usunięty tekst:
scl quotes delete --search-terms David "You can do" Antoine "Perfection is achieved"
Uwaga
Jeśli uruchamiasz plik w folderze bin/debug/net9.0, tam znajdziesz plik ze zmianami z poleceń add i delete. Kopia pliku w folderze projektu pozostaje niezmieniona.
Następne kroki
Podczas tego samouczka stworzyłeś prostą aplikację wiersza polecenia, która korzysta z System.CommandLine. Aby dowiedzieć się więcej o bibliotece, zobacz System.CommandLine omówienie.