Blog.Xinxing

Articles about tech, physics, and everything else related to life!

Tips for dotnet console apps

Scripts V.S. Console apps

People use scripts to run batch jobs or repeat themselves on every platform. In most cases, script is an ideal choice as it is a simple text file which is easy for human to share, understand and revise. A console app, on the other hand, is usually not so handy. First of all, it is normally a binary, which could not be directly understood and update by human. Secondly, it takes more efforts to distribute them since people will need to install these binaries before using them. However, dotnet console apps might be a better choice in many cases:
  • Script languages are not enough for the sophisticated logics of your tools. You need advanced and more formalized programming languages, like C#.
  • Better version control so that you know the exact version of code for each run.
  • You need a cross platform tool which runs on Windows, Mac OS and Linux.
Dotnet CLI by default provides a minimum, functional, template for console application. But it is far from the best practices. I am going to show you some tips, so that while leveraging all the benefits of a dotnet console app, you made it easy to be shared with others, and straight forward to understand. A full demo is shared on Github here.

Use command line parser

One nightmare to author a console app is to design the sub-commands and arguments/options while providing sufficient help information to tell your customers how to use it. A command line parser library helps a lot. In my demo I use Microsoft.Extensions.CommandLineUtils:
  • Create a CommandLineApplication to manage these information.
  • Provide app name and description.
  • Use HelpOption to provide the help text.
  • Use VersionOption to show version information.
  • Specify the code to run when users run the app directly without sub-commands.
  • Add sub-commands and corresponding command line options, help information, and code to execute.
  • Well organized command line options and sub-commands information are generated and printed in application’s help.
To see the output examples, read this section of the demo’s ReadMe.

Package and share as dotnet tool

A dotnet tool is a special NuGet package that contains a console application. For more information, read official document here. In my demo, I configured it with the following properties in the project file:
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <PackAsTool>true</PackAsTool>
    <ToolCommandName>DataProcessor</ToolCommandName>
    <PackageOutputPath>./nupkg</PackageOutputPath>
    <Version>0.0.1</Version>
  </PropertyGroup>
  • OutputType tells dotnet CLI that the output of this project is an executable.
  • TargetFramework is the framework to run this app on. Be sure to use netcoreapp2.1 or later which support dotnet tool.
  • PackAsTool tells dotnet CLI to pack this app as dotnet tool when running dotnet pack.
  • ToolCommandName is the command name to run the tool after installation.
  • PackageOutputPath is the output path of the NuGet package when build and pack with dotnet pack.
  • Version is the NuGet package version.
In this demo I reuse the NuGet package version as the console app’s version with these lines of C# code:
    app.VersionOption("-v|--version", () => {
        return string.Format("Version {0}", Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyInformationalVersionAttribute>().InformationalVersion);
    });
See more information about build, release and install from this section in the Readme.md.

Run the app faster

If you use the console app for batch processing you might want to run it faster. Make sure the correct flags are set for your dotnet so that all CPU cores are utilized. Read Speed up dotnet core app.

Build multiple binaries from one project

If you want to release different binaries to different customers while maintaining the code under one project, read Build multiple binaries from one project in dotnet.

Leave a Reply

Your email address will not be published. Required fields are marked *