Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Questa esercitazione illustra come creare un'app da riga di comando .NET che usa la System.CommandLine libreria. Si inizierà creando un semplice comando radice con un'unica opzione. Successivamente costruirai su quella base, creando un'app più complessa con più sottocomandi e opzioni diverse per ogni comando.
In questa esercitazione si apprenderà come:
- Creare comandi, opzioni e argomenti.
- Specificare i valori predefiniti per le opzioni.
- Assegnare opzioni e argomenti ai comandi.
- Assegnare un'opzione in modo ricorsivo a tutti i sottocomandi in un comando.
- Lavorare con più livelli di sottocomandi annidati.
- Creare alias per comandi e opzioni.
- Lavora con
string,string[],int,bool,FileInfoe tipi di opzioni di enumerazione. - Leggere i valori delle opzioni nel codice azione del comando.
- Usare codice personalizzato per l'analisi e la convalida delle opzioni.
Prerequisiti
oppure
- Visual Studio 2022 con il carico di lavoro per lo sviluppo desktop .NET installato.
Creare l'app
Creare un progetto di app console .NET 9 denominato "scl".
Creare una cartella denominata scl per il progetto e quindi aprire un prompt dei comandi nella nuova cartella.
Eseguire il comando seguente:
dotnet new console --framework net9.0
Installare il pacchetto System.CommandLine
Eseguire il comando seguente:
dotnet add package System.CommandLine --prereleaseIn alternativa, in .NET 10+:
dotnet package add System.CommandLine --prereleaseL'opzione
--prereleaseè necessaria perché la libreria è ancora in versione beta.
Analizzare gli argomenti
Sostituire il contenuto di Program.cs con il codice seguente:
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); } } }
Il codice precedente:
- Crea un'opzione denominata
--filedi tipo FileInfo e la aggiunge al comando radice:
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);
- Analizza
argse controlla se è stato specificato un valore per l'opzione--file. In tal caso, chiama il metodoReadFileusando il valore0elaborato e restituisce il codice di uscita:
ParseResult parseResult = rootCommand.Parse(args);
if (parseResult.Errors.Count == 0 && parseResult.GetValue(fileOption) is FileInfo parsedFile)
{
ReadFile(parsedFile);
return 0;
}
- Se non è stato specificato alcun valore per
--file, stampa gli errori di analisi disponibili e restituisce1il codice di uscita:
foreach (ParseError parseError in parseResult.Errors)
{
Console.Error.WriteLine(parseError.Message);
}
return 1;
- Il
ReadFilemetodo legge il file specificato e ne visualizza il contenuto nella console:
static void ReadFile(FileInfo file)
{
foreach (string line in File.ReadLines(file.FullName))
{
Console.WriteLine(line);
}
}
Testare l'app
È possibile usare uno dei modi seguenti per testare durante lo sviluppo di un'app da riga di comando:
Eseguire il
dotnet buildcomando e quindi aprire un prompt dei comandi nella cartella scl/bin/Debug/net9.0 per eseguire il file eseguibile:dotnet build cd bin/Debug/net9.0 scl --file scl.runtimeconfig.jsonUsare
dotnet rune passare i valori delle opzioni all'app anziché alruncomando includendoli dopo--, come nell'esempio seguente:dotnet run -- --file bin/Debug/net9.0/scl.runtimeconfig.json
Questa esercitazione presuppone che si stia usando la prima di queste opzioni.
Quando si esegue l'app, viene visualizzato il contenuto del file specificato dall'opzione --file .
{
"runtimeOptions": {
"tfm": "net9.0",
"framework": {
"name": "Microsoft.NETCore.App",
"version": "9.0.0"
}
}
}
Ma cosa succede se si chiede di visualizzare l'aiuto fornendo --help? Nulla viene stampato nella console, perché l'app non gestisce ancora lo scenario in cui --file non viene fornito e non sono presenti errori di analisi.
Analizzare gli argomenti e richiamare ParseResult
System.CommandLine consente di specificare un'azione richiamata quando un determinato simbolo (comando, direttiva o opzione) viene analizzato correttamente. L'azione è un delegato che accetta un parametro e restituisce un System.CommandLine.ParseResultint codice di uscita (sono disponibili anche azioni asincrone). Il codice di uscita viene restituito dal System.CommandLine.Parsing.ParseResult.Invoke metodo e può essere usato per indicare se il comando è stato eseguito correttamente o meno.
Sostituire il contenuto di Program.cs con il codice seguente:
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); } } }
Il codice precedente:
Specifica che
ReadFileè il metodo che verrà chiamato quando viene richiamato il comando radice:rootCommand.SetAction(parseResult => { FileInfo parsedFile = parseResult.GetValue(fileOption); ReadFile(parsedFile); return 0; });argsAnalizza e richiama il risultato:ParseResult parseResult = rootCommand.Parse(args); return parseResult.Invoke();
Quando si esegue l'app, viene visualizzato il contenuto del file specificato dall'opzione --file .
Cosa accade se chiedi di visualizzare la Guida usando --help?
scl --help
L'output seguente viene stampato:
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 per impostazione predefinita, fornisce l'opzione Guida, l'opzione Versione e la direttiva Suggerisci. Il ParseResult.Invoke(InvocationConfiguration) metodo è responsabile della chiamata dell'azione del simbolo analizzato. Potrebbe trattarsi dell'azione definita in modo esplicito per il comando o dell'azione della Guida definita da System.CommandLine per System.CommandLine.Help.HelpOption. Inoltre, quando rileva eventuali errori di analisi, li stampa nell'errore standard, stampa il messaggio di aiuto nell'output standard e restituisce 1 come codice di uscita.
scl --invalid bla
Unrecognized command or argument '--invalid'.
Unrecognized command or argument 'bla'.
Aggiungere un sottocomando e opzioni
In questa sezione, tu:
- Crea altre opzioni.
- Creare un sottocomando.
- Assegnare le nuove opzioni al nuovo sottocomando.
Le nuove opzioni consentono di configurare i colori del testo in primo piano e di sfondo e la velocità di lettura. Queste funzionalità verranno usate per leggere una collezione di citazioni provenienti dall'esercitazione sull'app console Teleprompter.
Copiare il filesampleQuotes.txt dal repository GitHub per questo esempio nella directory del progetto. Per informazioni su come scaricare i file, vedere le istruzioni in Esempi ed esercitazioni.
Aprire il file di progetto e aggiungere un
<ItemGroup>elemento subito prima del tag di chiusura</Project>:<ItemGroup> <Content Include="sampleQuotes.txt"> <CopyToOutputDirectory>Always</CopyToOutputDirectory> </Content> </ItemGroup>L'aggiunta di questo markup fa sì che il file di testo venga copiato nella cartella bin/debug/net9.0 quando si compila l'app. Pertanto, quando si esegue il file eseguibile in tale cartella, è possibile accedere al file in base al nome senza specificare un percorso di cartella.
In Program.cs, dopo il codice che crea l'opzione
--file, creare opzioni per controllare la velocità di lettura e i colori del testo: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." };Dopo la riga che crea il comando radice, eliminare il codice che aggiunge l'opzione
--file. Lo stai rimuovendo perché lo aggiungerai in un nuovo sottocomando.Dopo la riga che crea il comando radice, creare un
readsottocomando. Aggiungi le opzioni a questo sottocomando (usando la sintassi dell'inizializzatore di raccolta invece della proprietàOptions) e aggiungi il sottocomando al comando principale.Command readCommand = new("read", "Read and display the file.") { fileOption, delayOption, fgcolorOption, lightModeOption }; rootCommand.Subcommands.Add(readCommand);Sostituire il
SetActioncodice con il codice seguenteSetActionper il nuovo sottocomando:readCommand.SetAction(parseResult => ReadFile( parseResult.GetValue(fileOption), parseResult.GetValue(delayOption), parseResult.GetValue(fgcolorOption), parseResult.GetValue(lightModeOption)));Non si sta più chiamando
SetActionsul comando radice perché il comando radice non richiede più un'azione. Quando un comando include sottocomandi, in genere è necessario specificare uno dei sottocomandi quando si richiama un'app da riga di comando.Sostituire il
ReadFilemetodo action con il codice seguente: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)); } }
L'app avrà ora un aspetto simile al seguente:
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));
}
}
}
Testare il nuovo sottocomando
Ora se si tenta di eseguire l'app senza specificare il sottocomando, viene visualizzato un messaggio di errore seguito da un messaggio della Guida che specifica il sottocomando disponibile.
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.
Il testo della Guida per sottocomando read mostra che sono disponibili quattro opzioni. Mostra valori validi per l'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
Eseguire sottocomando read specificando solo l'opzione --file e si ottengono i valori predefiniti per le altre tre opzioni.
scl read --file sampleQuotes.txt
Il ritardo predefinito di 42 millisecondi per carattere causa una velocità di lettura lenta. È possibile velocizzarla impostando --delay un numero inferiore.
scl read --file sampleQuotes.txt --delay 0
È possibile usare --fgcolor e --light-mode per impostare i colori del testo:
scl read --file sampleQuotes.txt --fgcolor red --light-mode
Specificare un valore non valido per --delay e viene visualizzato un messaggio di errore:
scl read --file sampleQuotes.txt --delay forty-two
Cannot parse argument 'forty-two' for option '--int' as expected type 'System.Int32'.
Specificare un valore non valido per --file e si ottiene un'eccezione:
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''
Aggiungere sottocomandi e convalida personalizzata
Questa sezione crea la versione finale dell'app. Al termine, l'app avrà i comandi e le opzioni seguenti:
- comando root con un'opzione ricorsiva* denominata
--file-
quotescomando-
readcomando con opzioni denominate--delay,--fgcolore--light-mode -
addcomando con argomenti denominatiquoteebyline -
deletecomando con opzione denominata--search-terms
-
-
* Un'opzione ricorsiva è disponibile per il comando a cui è assegnata e ricorsivamente a tutti i relativi sottocomandi.
Ecco l'input della riga di comando di esempio che richiama ognuno dei comandi disponibili con le relative opzioni e argomenti:
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"
In Program.cs sostituire il codice che crea l'opzione
--filecon il codice seguente: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); } } };Questo codice usa
System.CommandLine.Parsing.ArgumentResultper fornire analisi, convalida e gestione degli errori personalizzati.Senza questo codice, i file mancanti vengono segnalati con un'eccezione e un'analisi dello stack. Con questo codice viene visualizzato solo il messaggio di errore specificato.
Questo codice specifica anche un valore predefinito, motivo per cui imposta
DefaultValueFactoryil metodo di analisi personalizzato.Dopo il codice che crea
lightModeOption, aggiungere opzioni e argomenti per iaddcomandi edelete: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." };L'impostazione
xref:System.CommandLine.Option.AllowMultipleArgumentsPerTokenconsente di omettere il nome dell'opzione--search-termsquando si specificano elementi nell'elenco dopo il primo. Rende equivalenti i seguenti esempi di input da riga di comando.scl quotes delete --search-terms David "You can do" scl quotes delete --search-terms David --search-terms "You can do"Sostituire il codice che crea il comando radice e il
readcomando con il codice seguente: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);Questo codice apporta le modifiche seguenti:
Rimuove l'opzione
--filedalreadcomando .Aggiunge l'opzione
--filecome opzione ricorsiva al comando radice.Crea un
quotescomando e lo aggiunge al comando radice.Aggiunge il
readcomando alquotescomando anziché al comando radice.Crea
addedeletecomandi e li aggiunge alquotescomando.
Il risultato è la gerarchia di comandi seguente:
- Comando principale
quotesreadadddelete
L'app implementa ora il modello consigliato in cui il comando padre (
quotes) specifica un'area o un gruppo e i relativi comandi figlio (read,add,delete) sono azioni.Le opzioni ricorsive vengono applicate al comando e in modo ricorsivo ai sottocomandi. Poiché
--fileè nel comando radice, sarà disponibile automaticamente in tutti i sottocomandi dell'app.Dopo il
SetActioncodice, aggiungere nuovoSetActioncodice per i nuovi sottocomandi:deleteCommand.SetAction(parseResult => DeleteFromFile( parseResult.GetValue(fileOption), parseResult.GetValue(searchTermsOption))); addCommand.SetAction(parseResult => AddToFile( parseResult.GetValue(fileOption), parseResult.GetValue(quoteArgument), parseResult.GetValue(bylineArgument)) );Il sottocomando
quotesnon ha un'azione perché non è un comando foglia. I sottocomandiread,addedeletesono comandi foglia sottoquotes, eSetActionviene chiamato per ognuno di questi sottocomandi.Aggiungere le azioni per
addedelete.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}"); }
L'app completata è simile alla seguente:
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}");
}
}
Compilare il progetto e quindi provare i comandi seguenti.
Inviare un file inesistente a --file con il read comando e viene visualizzato un messaggio di errore anziché un'eccezione e un'analisi dello stack:
scl quotes read --file nofile
File does not exist
Provare a eseguire sottocomando quotes e viene visualizzato un messaggio che indica di usare read, addo 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.
Eseguire sottocomando adde quindi esaminare la fine del file di testo per visualizzare il testo aggiunto:
scl quotes add "Hello world!" "Nancy Davolio"
Eseguire sottocomando delete con stringhe di ricerca dall'inizio del file e quindi esaminare l'inizio del file di testo per vedere dove è stato rimosso il testo:
scl quotes delete --search-terms David "You can do" Antoine "Perfection is achieved"
Annotazioni
Se si esegue nella cartella bin/debug/net9.0, quella sarà la posizione in cui si troverà il file con le modifiche apportate dai comandi add e delete. La copia del file nella cartella del progetto rimane invariata.
Passaggi successivi
In questa esercitazione è stata creata una semplice app da riga di comando che usa System.CommandLine. Per altre informazioni sulla libreria, vedere System.CommandLine panoramica.