Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Importante
System.CommandLine
está atualmente em pré-visualização e esta documentação destina-se à versão 2.0 beta 5.
Algumas informações estão relacionadas ao produto de pré-lançamento que pode ser substancialmente modificado antes de ser lançado. A Microsoft não oferece garantias, expressas ou implícitas, em relação às informações fornecidas aqui.
Este tutorial mostra como criar um aplicativo de linha de comando .NET que usa a System.CommandLine
biblioteca. Você começará criando um comando root simples que tem uma opção. Em seguida, você criará essa base, criando um aplicativo mais complexo que contém vários subcomandos e opções diferentes para cada comando.
Neste tutorial, você aprenderá a:
- Crie comandos, opções e argumentos.
- Especifique valores padrão para opções.
- Atribua opções e argumentos a comandos.
- Atribua uma opção recursivamente a todos os subcomandos sob um comando.
- Trabalhe com vários níveis de subcomandos encadeados.
- Crie aliases para comandos e opções.
- Trabalhe com
string
,string[]
,int
,bool
,FileInfo
e com tipos de opções enum. - Leia os valores da opção no código de ação do comando.
- Use código personalizado para analisar e validar opções.
Pré-requisitos
- O mais recente SDK do .NET
- Editor de código do Visual Studio
- O Kit de Desenvolvimento C#
Ou
- Visual Studio 2022 com a carga de trabalho de desenvolvimento desktop .NET instalada.
Criar a aplicação
Crie um projeto de aplicativo de console do .NET 9 chamado "scl".
Crie uma pasta chamada scl para o projeto e, em seguida, abra um prompt de comando na nova pasta.
Execute o seguinte comando:
dotnet new console --framework net9.0
Instalar o pacote System.CommandLine
Execute o seguinte comando:
dotnet add package System.CommandLine --prerelease
Ou, no .NET 10+:
dotnet package add System.CommandLine --prerelease
A
--prerelease
opção é necessária porque a biblioteca ainda está em versão beta.
Analise os argumentos
Substitua o conteúdo do ficheiro Program.cs pelo seguinte código:
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); } } }
O código anterior:
- Cria uma opção chamada
--file
de tipo FileInfo e a adiciona ao comando raiz:
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);
- Analisa o
args
e verifica se algum valor foi fornecido para a opção--file
. Em caso afirmativo, ele chama o métodoReadFile
usando o valor analisado e retorna o código de saída0
.
ParseResult parseResult = rootCommand.Parse(args);
if (parseResult.GetValue(fileOption) is FileInfo parsedFile)
{
ReadFile(parsedFile);
return 0;
}
- Se nenhum valor foi fornecido para
--file
, ele imprime erros de análise disponíveis e retorna1
o código de saída:
foreach (ParseError parseError in parseResult.Errors)
{
Console.Error.WriteLine(parseError.Message);
}
return 1;
- O
ReadFile
método lê o arquivo especificado e exibe seu conteúdo no console:
static void ReadFile(FileInfo file)
{
foreach (string line in File.ReadLines(file.FullName))
{
Console.WriteLine(line);
}
}
Testar a aplicação
Você pode usar qualquer uma das seguintes maneiras de testar durante o desenvolvimento de um aplicativo de linha de comando:
Execute o
dotnet build
comando e, em seguida, abra um prompt de comando na pasta scl/bin/Debug/net9.0 para executar o executável:dotnet build cd bin/Debug/net9.0 scl --file scl.runtimeconfig.json
Use
dotnet run
e passe valores de opção para o aplicativo em vez de para o comando,run
incluindo-os após--
, como no exemplo a seguir:dotnet run -- --file bin/Debug/net9.0/scl.runtimeconfig.json
Este tutorial pressupõe que você esteja usando a primeira dessas opções.
Quando você executa o aplicativo, ele exibe o conteúdo do arquivo especificado pela --file
opção.
{
"runtimeOptions": {
"tfm": "net9.0",
"framework": {
"name": "Microsoft.NETCore.App",
"version": "9.0.0"
}
}
}
Mas o que acontece se você pedir que ele exiba a ajuda fornecendo --help
? Nada é impresso no console, porque o aplicativo ainda não lida com o cenário onde --file
não é fornecido e não há erros de análise.
Analise os argumentos e invoque o ParseResult
System.CommandLine Permite especificar uma ação que é invocada quando um determinado símbolo (comando, diretiva ou opção) é analisado com êxito. A ação é um delegado que aceita um System.CommandLine.ParseResult
parâmetro e devolve um código de int
saída (ações assíncronas também estão disponíveis). O código de saída é retornado pelo System.CommandLine.Parsing.ParseResult.Invoke
método e pode ser usado para indicar se o comando foi executado com êxito ou não.
Substitua o conteúdo do ficheiro Program.cs pelo seguinte código:
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); } } }
O código anterior:
Especifica que o método
ReadFile
será chamado quando o comando raiz for invocado:rootCommand.SetAction(parseResult => { FileInfo parsedFile = parseResult.GetValue(fileOption); ReadFile(parsedFile); return 0; });
Analisa o
args
e invoca o resultado:ParseResult parseResult = rootCommand.Parse(args); return parseResult.Invoke();
Quando você executa o aplicativo, ele exibe o conteúdo do arquivo especificado pela --file
opção.
O que acontece se você pedir que ele exiba a ajuda fornecendo --help
?
scl --help
O seguinte resultado é impresso:
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
por padrão, fornece a opção Ajuda, a opção Versão e a diretiva Sugestão.
ParseResult.Invoke
método é responsável por invocar a ação do símbolo analisado. Pode ser a ação explicitamente definida para o nosso comando, ou a ação de ajuda definida por System.CommandLine
for System.CommandLine.Help.HelpOption
. Além disso, quando deteta erros de análise, imprime-os no erro padrão, imprime ajuda à saída padrão e devolve 1
o código de saída:
scl --invalid bla
Unrecognized command or argument '--invalid'.
Unrecognized command or argument 'bla'.
Adicionar um subcomando e opções
Nesta secção, pode:
- Crie mais opções.
- Crie um subcomando.
- Atribua as novas opções ao novo subcomando.
As novas opções permitirão configurar as cores do texto em primeiro plano e plano de fundo e a velocidade de leitura. Esses recursos serão usados para ler uma coleção de citações que vem do tutorial do aplicativo de console Teleprompter.
Copie o arquivo sampleQuotes.txt do repositório GitHub para este exemplo no diretório do projeto. Para obter informações sobre como baixar arquivos, consulte as instruções em Exemplos e tutoriais.
Abra o arquivo de projeto e adicione um
<ItemGroup>
elemento imediatamente antes da tag de fechamento</Project>
:<ItemGroup> <Content Include="sampleQuotes.txt"> <CopyToOutputDirectory>Always</CopyToOutputDirectory> </Content> </ItemGroup>
Adicionar essa marcação faz com que o arquivo de texto seja copiado para a pasta bin/debug/net9.0 quando você cria o aplicativo. Assim, quando você executa o executável nessa pasta, você pode acessar o arquivo pelo nome sem especificar um caminho de pasta.
No Program.cs, após o código que cria a opção, crie opções para controlar a velocidade de leitura e as cores do
--file
texto: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." };
Após a linha que cria o comando raiz, exclua o código que adiciona a
--file
opção a ele. Você está removendo-o aqui para adicioná-lo a um novo subcomando.Após a linha que cria o comando raiz, crie um
read
subcomando. Adicione as opções a este subcomando (usando a sintaxe do inicializador de coleção em vez daOptions
propriedade) e adicione o subcomando ao comando raiz.Command readCommand = new("read", "Read and display the file.") { fileOption, delayOption, fgcolorOption, lightModeOption }; rootCommand.Subcommands.Add(readCommand);
Substitua o
SetAction
código pelo seguinteSetAction
código para o novo subcomando:readCommand.SetAction(parseResult => ReadFile( parseResult.GetValue(fileOption), parseResult.GetValue(delayOption), parseResult.GetValue(fgcolorOption), parseResult.GetValue(lightModeOption)));
Você já não está a chamar o comando raiz
SetAction
porque o comando raiz já não precisa de uma ação. Quando um comando tem subcomandos, normalmente você precisa especificar um dos subcomandos ao invocar um aplicativo de linha de comando.Substitua o
ReadFile
método de ação pelo seguinte código: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)); } }
O aplicativo agora tem esta aparência:
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));
}
}
}
Testar o novo subcomando
Agora, se você tentar executar o aplicativo sem especificar o subcomando, receberá uma mensagem de erro seguida por uma mensagem de ajuda que especifica o subcomando disponível.
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.
O texto de ajuda para o subcomando read
mostra que quatro opções estão disponíveis. Ele mostra valores válidos para o 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
Execute o subcomando read
especificando apenas a --file
opção e você obterá os valores padrão para as outras três opções.
scl read --file sampleQuotes.txt
O atraso padrão de 42 milissegundos por caractere causa uma velocidade de leitura lenta. Você pode acelerá-lo definindo --delay
para um número mais baixo.
scl read --file sampleQuotes.txt --delay 0
Você pode usar --fgcolor
e --light-mode
definir cores de texto:
scl read --file sampleQuotes.txt --fgcolor red --light-mode
Forneça um valor inválido para --delay
e você receberá uma mensagem de erro:
scl read --file sampleQuotes.txt --delay forty-two
Cannot parse argument 'forty-two' for option '--int' as expected type 'System.Int32'.
Forneça um valor inválido para --file
e você obtém uma exceção:
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''
Adicionar subcomandos e validação personalizada
Esta seção cria a versão final do aplicativo. Quando terminar, o aplicativo terá os seguintes comandos e opções:
- comando root com uma opção recursiva* chamada
--file
-
quotes
comando-
read
com opções denominadas--delay
,--fgcolor
, e--light-mode
-
add
comando com argumentos nomeadosquote
ebyline
-
delete
comando com opção nomeada--search-terms
-
-
* Uma opção recursiva está disponível para o comando ao qual é atribuído e recursivamente para todos os seus subcomandos.
Aqui está um exemplo de entrada de linha de comando que invoca cada um dos comandos disponíveis com suas opções e argumentos:
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"
No Program.cs, substitua o código que cria a
--file
opção pelo seguinte código: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); } } };
Esse código é usado
System.CommandLine.Parsing.ArgumentResult
para fornecer análise, validação e tratamento de erros personalizados.Sem esse código, os arquivos ausentes são relatados com uma exceção e rastreamento de pilha. Com esse código, apenas a mensagem de erro especificada é exibida.
Esse código também especifica um valor padrão, e é por isso que ele define
DefaultValueFactory
como método de análise personalizado.Após o código que cria
lightModeOption
, adicione opções e argumentos para osadd
comandos 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." };
A configuração
xref:System.CommandLine.Option.AllowMultipleArgumentsPerToken
permite omitir o nome da opção--search-terms
ao especificar elementos na lista, após o primeiro. Ele torna equivalentes os seguintes exemplos de entrada de linha de comando:scl quotes delete --search-terms David "You can do" scl quotes delete --search-terms David --search-terms "You can do"
Substitua o código que cria o comando raiz e o
read
comando pelo seguinte código: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);
Este código faz as seguintes alterações:
Remover a opção
--file
do comandoread
.Adiciona a
--file
opção como uma opção recursiva ao comando root.Cria um
quotes
comando e o adiciona ao comando raiz.Adiciona o
read
comando aoquotes
comando em vez de ao comando raiz.Cria
add
edelete
comanda e adiciona-os aoquotes
comando.
O resultado é a seguinte hierarquia de comandos:
- Comando raiz
quotes
read
add
delete
O aplicativo agora implementa o padrão recomendado onde o comando pai (
quotes
) especifica uma área ou grupo, e seus comandos filhos (read
,add
,delete
) são ações.As opções recursivas são aplicadas ao comando e recursivamente aos subcomandos. Como
--file
está no comando root, ele estará disponível automaticamente em todos os subcomandos do aplicativo.Após o
SetAction
código, adicione novoSetAction
código para os novos subcomandos:deleteCommand.SetAction(parseResult => DeleteFromFile( parseResult.GetValue(fileOption), parseResult.GetValue(searchTermsOption))); addCommand.SetAction(parseResult => AddToFile( parseResult.GetValue(fileOption), parseResult.GetValue(quoteArgument), parseResult.GetValue(bylineArgument)) );
O subcomando
quotes
não tem uma ação porque não é um comando folha. Subcomandosread
,add
, edelete
são comandos folha emquotes
, eSetAction
é chamado para cada um deles.Adicione as ações para
add
edelete
.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}"); }
O aplicativo concluído tem esta aparência:
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}");
}
}
Crie o projeto e, em seguida, tente os seguintes comandos.
Submete um ficheiro inexistente para --file
usando o comando read
e receberás uma mensagem de erro em vez de uma exceção e rastreio de pilha:
scl quotes read --file nofile
File does not exist
Tente executar o subcomando quotes
e você receberá uma mensagem orientando você a usar read
, add
, ou 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.
Execute o subcomando add
e, em seguida, olhe para o final do arquivo de texto para ver o texto adicionado:
scl quotes add "Hello world!" "Nancy Davolio"
Execute o subcomando delete
com cadeias de caracteres de pesquisa desde o início do arquivo e, em seguida, examine o início do arquivo de texto para ver onde o texto foi removido:
scl quotes delete --search-terms David "You can do" Antoine "Perfection is achieved"
Observação
Se estiveres a executar na pasta bin/debug/net9.0, é nessa pasta que encontrarás o ficheiro com as alterações dos comandos add
e delete
. A cópia do arquivo na pasta do projeto permanece inalterada.
Próximos passos
Neste tutorial, criaste uma aplicação de linha de comando simples que utiliza System.CommandLine
. Para saber mais sobre a biblioteca, consulte System.CommandLine Visão geral.