How can we override the behavior of --version in C# with System.Commandline?
The default implementation unfortunately only shows the version of the app itself, which is rarely useful. If support asks for the version, they usually need more than just the app version and we want to show additional information:
Of course, we don't want two different command line options to display the version, because then we would have to repeatedly explain that they should not use the standard --version parameter (because it is useless).
Hence my question:
--version option in System.CommandLine?--version?Thanks a lot for any help!
Thomas
I assume you are using the daily builds from https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-libraries/nuget/v3/index.json as nuget.org hasn't seen a release in ~2 years.
Above feed URL is listed in the repo itself Github dotnet/command-line-api Daily Builds
With 2.0.0-beta4.24528.1 I found e.g. the following works just fine.
static async Task<int> Main(string[] args)
{
var rootCommand = new CliRootCommand();
for (int i = 0; i < rootCommand.Options.Count; i++)
{
if (rootCommand.Options[i] is VersionOption)
rootCommand.Options[i].Action = new YourVersionOptionAction();
}
CliConfiguration config = new(rootCommand);
return await config.InvokeAsync(args);
}
public sealed class YourVersionOptionAction : SynchronousCliAction
{
public override int Invoke(ParseResult parseResult)
{
var appVersion = Assembly.GetExecutingAssembly().GetName().Version;
var runtimeVersion = Environment.Version;
parseResult.Configuration.Output.WriteLine($"App Version: {appVersion}");
parseResult.Configuration.Output.WriteLine($".NET Runtime Version: {runtimeVersion}");
return 0;
}
}
I could imagine there is a more elegant/idiomatic way but the docs aren't up-2-date with the repo and I couldn't be bothered to look further
I have found another solution using a Middleware handler:
public class Program {
static async Task<int> Main(string[] args) {
var rootCommand2 = new RootCommand("Sample app for System.CommandLine");
// Create the CommandLineBuilder with and add the Middleware
var builder = new CommandLineBuilder(rootCommand2)
// Set option verb & shortcut
.UseVersionOption("--version", "-v")
.AddMiddleware(VersionMiddleware_Handler, MiddlewareOrder.ExceptionHandler)
.UseDefaults();
var parser = builder.Build();
return await parser.InvokeAsync(args);
}
/// <summary>
/// Changes the Handler for -v / --version
/// </summary>
/// <param name="context"></param>
public static void VersionMiddleware_Handler(InvocationContext context) {
// Search the --version Option in RootCommand
var versionOption = context.ParseResult.CommandResult.Command.Options
.FirstOrDefault(o => o.Aliases.Contains("--version"));
if (versionOption != null) {
// Test, if the commandline token matches an alias
var isVersionRequested = context.ParseResult.Tokens
.Any
(t => versionOption.Aliases.Contains
(t.Value, StringComparer.InvariantCultureIgnoreCase));
if (isVersionRequested) {
// Changes the output for --version
var version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
Console.WriteLine($"Version: {version}");
Console.WriteLine("Additional Data :-)");
Environment.Exit(0);
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With