The lowly console application has gotten a sad reputation in the .NET ecosystem. Generally, the project format is relegated to the arena of the demonstration. We’re all guilty of starting and abandoning that ConsoleApp341 project. It is time the console app gets the respect it deserves.

The flourishing of terminal technologies are starting a renaissance of enhanced user experiences. From iTerm2, Hyper, and Windows Terminal, all these tools add some spice to an otherwise drab and boring console experience. These tools allow a user to customize their experience, but developers also want to add some programmatic flair to their console apps.

In this post, we’re going to see how we can spice up our console projects and upgrade the user experience using some great open-source projects. Presented in no particular order, here are some fantastic ways to enhance our console app experiences.

Colorful.Console

Colorful.Console is a Nuget package that gives us enhanced control of the output of any console text rendering. We can use colors from System.Drawing.Color to define the color scheme of our console apps.

using System;
using System.Drawing;
using Console = Colorful.Console;
...
...
Console.WriteLine("console in pink", Color.Pink);
Console.WriteLine("console in default");

color console basic usage

Not only that, Colorful.Console, allows us to write color ASCII output using FIGlet fonts.

FigletFont font = FigletFont.Load("chunky.flf");
Figlet figlet = new Figlet(font);

Console.WriteLine(figlet.ToAscii("Belvedere"), ColorTranslator.FromHtml("#8AFFEF"));
Console.WriteLine(figlet.ToAscii("ice"), ColorTranslator.FromHtml("#FAD6FF"));
Console.WriteLine(figlet.ToAscii("cream."), ColorTranslator.FromHtml("#B8DBFF"));

The output is straight out of a hacker’s dream.

color console figlet usage

I recommend visiting [the documentation site][colorful.console] and seeing all the ways this library can change the console experience.

ConsoleTables

ConsoleTables package is a bit of shameless promotion. The library is written by me, Khalid Abuhakmeh. The library allows developers to easily output an array of items into a formatted table in the console’s output.

static void Main(String[] args)
{
    var table = new ConsoleTable("one", "two", "three");
    table.AddRow(1, 2, 3)
         .AddRow("this line should be longer", "yes it is", "oh");

    table.Write();
    Console.WriteLine();

    var rows = Enumerable.Repeat(new Something(), 10);

    ConsoleTable
        .From<Something>(rows)
        .Configure(o => o.NumberAlignment = Alignment.Right)
        .Write(Format.Alternative);

    Console.ReadKey();
}

Who hasn’t wanted to output a table in a console application before?

FORMAT: Default:

 --------------------------------------------------
 | one                        | two       | three |
 --------------------------------------------------
 | 1                          | 2         | 3     |
 --------------------------------------------------
 | this line should be longer | yes it is | oh    |
 --------------------------------------------------

 Count: 2


FORMAT: Alternative:

+----------------------------+-----------+-------+
| one                        | two       | three |
+----------------------------+-----------+-------+
| 1                          | 2         | 3     |
+----------------------------+-----------+-------+
| this line should be longer | yes it is | oh    |
+----------------------------+-----------+-------+

Since publishing ConsoleTables, many other developers have created unique versions solving this problem. Some might even be better, so check them out.

ShellProgressBar

Console applications, like many other applications, can perform long-running tasks. ShellProgressBar is a fantastic library that outputs some visually stunning progress bars. It can also nest progress bars as children. Look at the following hypnotic GIF.

shellprogressbar

Usage is straightforward.

const int totalTicks = 10;
var options = new ProgressBarOptions
{
    ProgressCharacter = '─',
    ProgressBarOnBottom = true
};
using (var pbar = new ProgressBar(totalTicks, "Initial message", options))
{
    pbar.Tick(); //will advance pbar to 1 out of 10.
    //we can also advance and update the progressbar text
    pbar.Tick("Step 2 of 10"); 
}

Thank you, Martijn Laarman, for an excellent library.

GUI.CS

GUI.CS is a bonkers console UI toolkit. It offers a full-blown toolbox to build a user interface reminiscent of the early days of computing.

guics

The UI toolbox includes:

  • Buttons
  • Labels
  • Text Entry
  • Text View
  • User Inputs
  • Windows
  • Menus
  • ScrollBars

It is incredible what developers can do in a console application. Written by Miguel De Icaza, this library is the pinnacle of console technology. Let us take a look at the sample console application.

using Terminal.Gui;

class Demo {
    static void Main ()
    {
        Application.Init ();
        var top = Application.Top;

	// Creates the top-level window to show
        var win = new Window ("MyApp") {
	    X = 0,
	    Y = 1, // Leave one row for the toplevel menu

	    // By using Dim.Fill(), it will automatically resize without manual intervention
	    Width = Dim.Fill (),
	    Height = Dim.Fill ()
	};
        top.Add (win);

	// Creates a menubar, the item "New" has a help menu.
        var menu = new MenuBar (new MenuBarItem [] {
            new MenuBarItem ("_File", new MenuItem [] {
                new MenuItem ("_New", "Creates new file", NewFile),
                new MenuItem ("_Close", "", () => Close ()),
                new MenuItem ("_Quit", "", () => { if (Quit ()) top.Running = false; })
            }),
            new MenuBarItem ("_Edit", new MenuItem [] {
                new MenuItem ("_Copy", "", null),
                new MenuItem ("C_ut", "", null),
                new MenuItem ("_Paste", "", null)
            })
        });
        top.Add (menu);

	var login = new Label ("Login: ") { X = 3, Y = 2 };
	var password = new Label ("Password: ") {
	    	X = Pos.Left (login),
		Y = Pos.Top (login) + 1
        };
	var loginText = new TextField ("") {
                X = Pos.Right (password),
                Y = Pos.Top (login),
                Width = 40
        };
        var passText = new TextField ("") {
                Secret = true,
                X = Pos.Left (loginText),
                Y = Pos.Top (password),
                Width = Dim.Width (loginText)
        };
	
	// Add some controls, 
	win.Add (
	    // The ones with my favorite layout system
  	    login, password, loginText, passText,

	    // The ones laid out like an australopithecus, with absolute positions:
            new CheckBox (3, 6, "Remember me"),
            new RadioGroup (3, 8, new [] { "_Personal", "_Company" }),
            new Button (3, 14, "Ok"),
            new Button (10, 14, "Cancel"),
            new Label (3, 18, "Press F9 or ESC plus 9 to activate the menubar"));

        Application.Run ();
    }
}

This sample has everything and the kitchen sink in it.

Conclusion

As developers, we can get be enamored with GUIs, and rightfully so. They empower us to be productive. The console application is just as powerful. Next time you build a console application, be sure to reach for some of these libraries to add some flair to your solution. Regardless of the user’s terminal, they should have similar experiences with these libraries. Give them a try and let me know what you think. Thank you for reading, and please leave your comments below.