DEV Community

Marcos Costa
Marcos Costa

Posted on

Criando uma console application com esteróides com o pacote System.CommandLine

Olá devs! Já se pergutaram como os devs criam consoles application bem pomposas como essas do dotnet, cheias de comandos e listagem do que elas fazem?
dotnet console application

Então vamos lá começar com o feijão com arroz e criar uma console application no visual studio, ou se você prefirir, dá para usar o command line do dotnet para isso. Meus exemplos serão no Visual studio 2022 Community, mas você pode usar até um bloco de notas com a dotnet tool que funcionará.

Criando a console aplication

  • crie um novo projeto do tipo console application.
    Criando um novo projeto console no visual studio 2022

  • Após sua criação, importe o pacote nuget System.CommandLine

Botão direito do mouse em dependencias do projeto, selecionando Manager Nuget Package

Na barra de procura, procure por System.CommandLine, mas não se esqueça de marcar a opção include prerelease. E então click em install para instalar a dependência no seu projeto.

Busca por System.CommandLine e selecionando include prerelease

  • Agora substitua o código inicial da sua Program.cs pelo codigo abaixo:
using System.CommandLine;

// Crie uma descrição que será exibida caso o usuario não passe nenhum argumento.
// Isso também serve para você escrever uma descrição da sua ferramenta console.
var description = @"
Bem vindo ao meu console charmosão com vários 
comandos listados e documentados";

var rootCommand = new RootCommand(description);

// Criando um argumento a ser aceito por nosso app
var mensagemArg = new Argument<string>("Uma Mensagem", "Apenas essa mensagem será exibida");

// adicionando esse argumento no nosso comando principal
rootCommand.AddArgument(mensagemArg);

// Definindo uma ação para quando esse comando for adicionado.
rootCommand.SetHandler((mensagemArgValue) =>
{
   Console.WriteLine(mensagemArgValue); //Apenas exibe a mensagem recebida

}, mensagemArg);

// Passe os argumentos recebidos pela a console aplication para o objeto rootCommand 
// através do seu metódo invoke.
rootCommand.Invoke(args);
Enter fullscreen mode Exit fullscreen mode

Agora execute a sua aplicação console

Clique em executar

e voilá, temos nossa aplicação rodando com a descrição que colocamos

Exibição do menu do console application

A keyword args

Uma pequena explicação sobre a keyword args que passada como parametro na rootCommand.Invoke(args);: Todo console application pode aceitar argumentos como parametro inicial, dentro do C# ela é recebida através de uma array de strings, esse array de string é identificado quando você executa um comando separando as palavras por espaço.

Adicionando nossos primeiros argumentos

Essa lib é bem poderosa e conseguimos até mesmo definir quais argumentos são esperados e a ordem que eles devem acontecer, como você pode ver no código abaixo, onde definimos que o primeiro argumento recebido será uma string

// Criando um argumento a ser aceito por nosso app
var mensagemArg = new Argument<string>("Uma Mensagem", "Apenas essa mensagem será exibida");

// adicionando esse argumento no nosso comando principal
rootCommand.AddArgument(mensagemArg);

// Definindo uma ação para quando esse comando for adicionado.
rootCommand.SetHandler((mensagemArgValue) =>
{
   Console.WriteLine(mensagemArgValue); //Apenas exibe a mensagem recebida

}, mensagemArg);
Enter fullscreen mode Exit fullscreen mode

Mas também podemos mudar para dizer que receberemos um inteiro (int), um double (double), um arquivo (FileInfo), um diretório (DirectoryInfo) e varios outros tipos.

Opções para comandos

Também é possível fazer ações como o comando

dotnet restore [project.csproj/solution.sln] --build release

Vamos criar algo semelhante a isso nesse nosso ConsoleCharmosao, onde teremos um novo comando chamado length que receberá uma string e retornará a quantidade de caracteres contida nela.
Teremos que mudar nosso Código para chear proximo disso.

using System.CommandLine;

// Crie uma descrição que será exibida caso o usuario não passe nenhum argumento.
// Isso também serve para você escrever uma descrição da sua ferramenta console.
var description = @"
Bem vindo ao meu console charmosão com vários 
comandos listados e documentados";

var rootCommand = new RootCommand(description);

// Crie um novo comando
var lengthCommand = new Command("length", "Quantidade de caracteres em uma string");

// define nomes alternativos para chamar esse comando
lengthCommand.AddAlias("len");
lengthCommand.AddAlias("l");

// crie novo argumento a 
var lengthArgument = new Argument<string>("string", "string para ser processada");
lengthArgument.SetDefaultValue(string.Empty);

// adicione o novo argumento ao comando
lengthCommand.AddArgument(lengthArgument);

// crie uma nova opção
var lengthOptionRepeat = new Option<int>("--repeat", "Imprime quantas vezes?");
lengthOptionRepeat.AddAlias("-r");
lengthOptionRepeat.SetDefaultValue(1);

// adicione essa opção ao lengthComand
lengthCommand.AddOption(lengthOptionRepeat);

lengthCommand.SetHandler((lengthArgumentValue, lengthOptionRepeatValue) =>
{
    // recendo os valores e processando-os
    for (int i = 0; i < lengthOptionRepeatValue; i++) 
    {
        Console.WriteLine($"{i + 1}. {lengthArgumentValue.Length}");
    }

}, lengthArgument, lengthOptionRepeat); // lembre-se de passar os parametros aqui


// adicionando o length command ao nosso comando principal
rootCommand.AddCommand(lengthCommand);

// Passe os argumentos recebidos pela a console aplication para o objeto rootCommand 
// através do seu metódo invoke.
rootCommand.Invoke(args);
Enter fullscreen mode Exit fullscreen mode

Olha só como ficou nosso console após adição desse comando e option na sessão Commands

Listagem de comandos e execuções

Como testar?

Para testar dentro do visual studio 2022 é possivel definir lauchSettings.json onde eu defini abaixo

{
  "profiles": {
    "ConsoleCharmosao": {
      "commandName": "Project"
    },
    "StringLength": {
      "commandName": "Project",
      "commandLineArgs": "length \"minha string\" --repeat 3"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

lauchSettings.json

Caso, o lauchSettings.json não esteja aprecendo para você, execute as ações abaixo

  • Clique nas opções de execução (setinha para baixo), depois click em debug properties Indo pra debug properties

Na janela que abriu, selecione o botão de adicionar configuração, e selecione projeto. Após isso, você pode adicionar o comando que deseja executar na hora de rodar o aplicativo.

Novo comando StringLength adicionado

Agora você capaz de rodar e debugar seu comando direto do visual studio.

Deploy e execução

Quando você definir suas configurações de publicação, lembresse de definir o deployment mode como Self-contained.

Publish profile

Com o .exe publicado, você poderá rodar comandos como ConsoleCharmosao.exe length "minha string" --repeat 3

Obrigado!

De agora em diante você sabe fazer um console cheio de firulas e comandos utéis e assim ajudar no DX e UX de suas futuras ferramentas. Qualquer duvida deixa nos comentarios, você pode acessar o código fonte aqui, Me siga no Github e no Twitter/X.

Top comments (0)