Mike Tolland

Welcome to my blog

This is the start of my developer blog about CSharp and other various topics. This blog is using Jekyll and my own personal Gitlab combining the two to deploy a static site to my host provider. This blog is also edited via VSCode my ide/editor of choice now a days.

I will be using this blog to talk about programming and other engineering topics. I will also talk about life and various topics of interest to me.

The first topic on the docket is command line tools, also called CLI(command line interface). Recently with the explosion of the web programming language javascript many cli tools have been developed to be used with it. Even the new CSharp NET Core is using cli called dotnet. This got me thinking about how to create my own and if I should. What are the pro and cons of creating your own cli and how is this different from say a launcher tool like executor or launchy for windows.

I set out on creating my own command line tool to see what I could do and I found it to be really cool. We all probably using various tools to increase our efficiency like auto hotkey, quick silver, conemu, launchy, etc. But not everything does what we want it to do so if I could make a simple program to create a folder and setup directories how I like wouldn’t that be useful to me. It could be as simple as

<commandline> new project

Or maybe I have word document template that I like to use often and I can just go

<commandline> init wordTemplate New_Project

And it would create a word file at my current location with the name New_Project maybe even filling in some settings in the document.

So if your going to create your own what do you need if your using C# I recommend the following libraries Command Line Parser. This is a nuget library that allows you to parse command line arguements to objects in your application. I recommend using an interface to dynamically associate verbs like such

var parser = new Parser(config => config.HelpWriter = Console.Out);
var verbs = typeof(Program).Assembly.DefinedTypes.Where(t => t.CustomAttributes.Any(a => a.AttributeType == typeof(VerbAttribute))).Select(ti => ti.AsType()).ToArray();
var result = parser.ParseArguments(args, verbs);

This code will look through your executable and find all the verbs and load them into the parser. Next you might be wondering don’t you now have to statically map each verb to a result? Well not if you come up with some interfaces to execute the verbs like such

interface IVerb{
    void Execute();

result.WithParsed<IVerb>(verb => verb.Execute());

Now if you assign the IVerb interface to every class that implements the VerbAttribute you will be all set. Now everything is dynamic so you can quickly add new verbs without having to do anything. You can even implement a plugin system where someone will drop a new dll next to your executable and the types are added to the parser.

Another key aspect is that your commandline tool should be self contained. This means when you distribute it your just distributing a single file rather than a folder of dlls. There are a number of ways to do this which I will talk about during the next couple of days but the one that is the easiet is Costura a nuget package part of the Fody Collection. This is probably the easiet way to do this but it is limited. How it works is that it will embed all your reference dlls into the main executable and will also inject code to load the assemblies.

With these tools you can start creating your CLI like I did. I will talk more about embedding dlls in future posts since I find it to be very useful. One key thing to remember about Costura is that it only works on executables not dlls so if you need that you should check out Libz which I will talk about in the future.

Share this: