Uwaga
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Ważne
System.CommandLine
jest obecnie dostępna w wersji zapoznawczej, a ta dokumentacja dotyczy wersji 2.0 beta 5.
Niektóre informacje odnoszą się do produktu w wersji wstępnej, który może zostać znacząco zmodyfikowany przed jego wydaniem. Firma Microsoft nie udziela żadnych gwarancji, wyraźnych ani domniemanych, w odniesieniu do podanych tutaj informacji.
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
,FileInfo
i 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 --prerelease
Lub w .NET 10+:
dotnet package add System.CommandLine --prerelease
Opcja
--prerelease
jest 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.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
--file
typu 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
args
i sprawdza, czy dla opcji--file
podano jakąkolwiek wartość. Jeśli tak, wywołuje metodęReadFile
przy użyciu przeanalizowanej wartości i zwraca0
kod zakończenia:
ParseResult parseResult = rootCommand.Parse(args);
if (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 zwraca1
kod zakończenia:
foreach (ParseError parseError in parseResult.Errors)
{
Console.Error.WriteLine(parseError.Message);
}
return 1;
- Metoda
ReadFile
odczytuje 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 build
Uruchom 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.json
Użyj
dotnet run
i 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
ReadFile
jest 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
args
i 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
System.CommandLine.RootCommand
domyślnie udostępnia opcję Pomoc, opcję Wersji i dyrektywę Sugerowanie.
ParseResult.Invoke
Metoda jest odpowiedzialna za wywoływanie akcji przeanalizowanego symbolu. Może to być akcja jawnie zdefiniowana dla naszego polecenia lub akcja pomocy zdefiniowana przez System.CommandLine
dla System.CommandLine.Help.HelpOption
. Ponadto, gdy wykryje błędy analizy, drukuje je do standardowego błędu, drukuje pomoc dla standardowych danych wyjściowych i zwraca 1
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ę
--file
utwó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ę
--file
do 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
SetAction
następującym kodemSetAction
dla nowego podpolecenia:readCommand.SetAction(parseResult => ReadFile( parseResult.GetValue(fileOption), parseResult.GetValue(delayOption), parseResult.GetValue(fgcolorOption), parseResult.GetValue(lightModeOption)));
Nie wywołujesz
SetAction
już 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ę
ReadFile
akcji 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
-
read
polecenie z opcjami o nazwie--delay
,--fgcolor
i--light-mode
-
add
polecenie z argumentami o nazwachquote
ibyline
-
delete
komenda 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ę
--file
nastę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.ArgumentResult
w 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
DefaultValueFactory
na niestandardową metodę analizowania.Po kodzie tworzącym
lightModeOption
dodaj opcje i argumenty dla poleceńadd
idelete
: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.AllowMultipleArgumentsPerToken
pozwala pominąć nazwę opcji--search-terms
podczas 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
read
nastę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ę
--file
z poleceniaread
.Dodaje opcję
--file
jako opcję rekursywną do polecenia głównego.Tworzy polecenie
quotes
i dodaje je do głównego polecenia.Dodaje polecenie
read
do poleceniaquotes
zamiast do polecenia głównego.Tworzy polecenia
add
idelete
i dodaje je do poleceniaquotes
.
Wynikiem jest następująca hierarchia poleceń:
- Polecenie główne
quotes
read
add
delete
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ż
--file
jest w poleceniu głównym, będzie on automatycznie dostępny we wszystkich podpoleceniach aplikacji.Po kodzie
SetAction
dodaj nowy kodSetAction
dla 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
quotes
nie ma akcji, ponieważ nie jest to polecenie końcowe. Podpoleceniaread
,add
idelete
są poleceniami końcowymi wquotes
, aSetAction
jest wywoływane dla każdego z nich.Dodaj akcje dla
add
idelete
.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
, add
lub 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.