.NET Tool Example

Create a .NET tool using the .NET CLI
Published on Sunday 11 May 2025

https://neosmart.net/blog/new-dot-net-standard-framework-logo/

In this tutorial I will expand on the Microsoft Learn tutorials site. They give a great starting point for the minimum settings you need but I'll add a couple more I've found useful. See the 🔗 links at the end if you want to run through them.

Once you have created a new .NET exe, aka Console App, you can start updating the necessary config.

On the .csproj click Alt + Enter or Right-Click Properties.

Scroll down to Package and complete the properties you require. This will update the underlying .csproj or you could change them there directly but be careful as some only allow certain values.

In the original Tutorial they suggest the following:

<PackAsTool>true</PackAsTool>
<ToolCommandName>botsay</ToolCommandName>
<PackageOutputPath>./nupkg</PackageOutputPath>

Which is the minium you need, but I like to add a few more i.e. the ones below, to add an icon, tags, description etc to make it easier for your consumers and yourself to know what the app does.

General

Name Description Property
Generate NuGet package on build Produce a package file during build operations. GeneratePackageOnBuild
Package ID The case-insensitive package identifier, which must be unique across nuget.org or whatever gallery the package resides in. IDs may not contain spaces or characters that are not valid for a URL, and generally follow .NET namespace rules. PackageId
Title A human-friendly title of the package, typically used in Ul displays as on nuget.org and the Package Manager in Visual Studio. Title
Package Version The version of the package, following the major.minor.patch pattern. Version numbers may include a pre-release suffix. Version
Authors A comma-separated list of packages authors, matching the profile names on nuget.org. These are displayed in the NuGet Gallery on nuget.org and are used to cross-reference packages by the same authors. Authors
Company Company
Product Product
Description A description of the package for UI display. Description
Copyright Copyright details for the package. Copyright
Project URL A URL for the package's home page, often shown in UI displays as well as nuget.org. PackageProjectUrl
Icon The icon image for the package. Image file size is limited to 1 MB. Supported file formats include JPEG and PNG. An image resolution of 128x128 is recommended. PackageIcon
README The README document for the package. Must be a Markdown (.md) file. PackageIcon
Repository URL Specifies the URL for the repository where the source code for the package resides and/or from which it's being built. For linking to the project page, use the 'Project URL' field, instead. RepositoryUrl
Repository type Specifies the type of the repository. Default is 'git'. RepositoryType
Tags A semicolon-delimited list of tags and keywords that describe the package and aid discoverability of packages through search and filtering. PackageTags
Release notes A description of the changes made in this release of the package, often used in UI like the Updates tab of the Visual Studio Package Manager in place of the package description. PackageReleaseNotes
Pack as a .NET tool Packs this project as a special package that contains a console application that may be installed via the "dotnet tool" command. PackAsTool
NET tool command name The command name via which the .NET tool will be invoked on the command line. ToolCommandName
Package Output Path Determines the output path in which the package will be dropped. PackageOutputPath
Assembly neutral language (None) NeutralLanguage
Assembly version AssemblyVersion
File version FileVersion

License

Name Description Property
Package License Specify a license for the project's package. None
SPDX License Expression
Embedded File
License file PackageLicenseFile
Require license acceptance Prompt the user to accept the license when installing this package PackageRequireLicenseAcceptance
License expression An SPDX license expression, often shown in UIs like nuget.org PackageLicenseExpression link

Symbols

Name Description Property
Produce a symbol package Create an additional symbol package when the project is packed. IncludeSymbols
Symbol package format Specifies the format of the symbols package. SymbolPackageFormat (symbols.nupkg/snupkg)

.NET .NET .NET

This translates to the following:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net9.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>

    <!-- package properties -->
    <PackageId>alexhedley.botsay</PackageId>
    <Version>1.0.0</Version>
    <Authors>Alex Hedley</Authors>
    <Company>Alex Hedley</Company>
    <Product>Microsoft BotSay</Product>

    <Title>Microsoft Bot Say</Title>
    <PackageTags>Microsoft;Bot;Say</PackageTags>
    <Description>This tool is a console application that takes a message as input and displays the message along with lines of text that create the image of a robot.</Description>
    <PackageIcon>icon.png</PackageIcon>
    <PackageReadmeFile>README.md</PackageReadmeFile>
    <PackageRequireLicenseAcceptance>False</PackageRequireLicenseAcceptance>
    <PackageLicenseFile>LICENSE</PackageLicenseFile>
    <!-- <PackageLicenseExpression>MIT</PackageLicenseExpression> -->
    <PackageReleaseNotes>Release Notes are the following...</PackageReleaseNotes>
    <RepositoryType>git</RepositoryType>
    <RepositoryUrl>https://github.com/AlexHedley/dotnet-tool-example</RepositoryUrl>
    <PackageProjectUrl>https://github.com/AlexHedley/dotnet-tool-example</PackageProjectUrl>
    <Copyright>© 2025</Copyright>
    
    <!-- Tool settings -->
    <PackAsTool>true</PackAsTool>
    <ToolCommandName>botsay</ToolCommandName>
    <PackageOutputPath>./nupkg</PackageOutputPath>
    <!-- <GeneratePackageOnBuild>true</GeneratePackageOnBuild> -->
  </PropertyGroup>

  <ItemGroup>
    <None Include="..\..\LICENSE" Pack="true" PackagePath="\" />
    <None Include="images\icon.png" Pack="true" PackagePath="" />
    <None Include="..\assets\README.md" Pack="true" PackagePath="" />
  </ItemGroup>

</Project>

Build the app then open the .nupkg it in the NuGet Package Explorer to confirm if your properties have been set correctly.

NuGet Package Explorer

If you don't have the app installed you can find it on GitHub or the Microsoft Store.

</> Code

You can download the example I built on GitHub.

Release: https://github.com/AlexHedley/dotnet-tool-example/releases/tag/1.0.0
GitHub nuget: https://github.com/AlexHedley/dotnet-tool-example/pkgs/nuget/alexhedley.botsay
nuget: https://www.nuget.org/packages/alexhedley.botsay/