Why C# is ideal for CLI tools, and why this matters for a Python developer
\nWhen we talk about creating console utilities, the first things that come to mind are Python, Bash, or Go. But what if I told you that C# is one of the most underrated languages for writing fast, cross-platform, and beautiful CLI tools? Yes, that same C# that many associate with web forms and corporate monsters.
\nWith the release of .NET 6/8, C# has gained minimal API, native compilation (AOT), and the incredibly convenient System.CommandLine library. Now you can create a utility that works on Windows, Linux, and macOS in literally 15 minutes. For students and developers learning Python, this is a great way to expand your toolkit and understand how CLI utilities work in other languages.
In this article, we won't just write "Hello World". We will create a full-fledged file utility that can parse arguments, output colored text, handle errors, and even show a progress bar. Let's go!
\n\nProject setup: minimal effort
\nThe first thing to do is make sure you have the .NET SDK installed (version 6.0 or higher). Check it simply:
\ndotnet --version\nIf everything is fine, create a new console project:
\ndotnet new console -n FileGuardian\ncd FileGuardian\nAt this stage, we already have a ready-made skeleton. But for a real CLI utility, we need a library for argument parsing. Add it:
\ndotnet add package System.CommandLine --version 2.0.0-beta4.22272.1\nDone. Now we have everything to create a professional console application in C#.
\n\nWhy System.CommandLine instead of manual parsing?
\nMany beginners write args[0], args[1] and catch IndexOutOfRangeException. This is the path of pain. System.CommandLine gives you:
- \n
- Automatic parsing of flags (
--output,-o) \n - Hints on incorrect input \n
- Built-in
--helpgeneration \n - Support for subcommands (like in git) \n
This is a must-have for any serious C# console utility.
\n\nWriting the utility core: the first command
\nImagine we are creating a file monitoring tool — FileGuardian. It will check file sizes and warn if they exceed a limit. Sounds useful, right?
\nOpen Program.cs and write the following:
using System.CommandLine;\n\nvar rootCommand = new RootCommand("FileGuardian — file monitoring utility");\n\nvar fileOption = new Option<FileInfo?>(\n name: "--file",\n description: "Path to the file for analysis"\n);\nrootCommand.AddOption(fileOption);\n\nrootCommand.SetHandler((file) =>\n{\n if (file is null || !file.Exists)\n {\n Console.Error.WriteLine("❌ File not found!");\n return;\n }\n \n long sizeInBytes = file.Length;\n double sizeInMb = sizeInBytes / (1024.0 * 1024.0);\n \n Console.WriteLine($"📄 File: {file.Name}");\n Console.WriteLine($"📏 Size: {sizeInMb:F2} MB");\n \n if (sizeInMb > 100)\n Console.WriteLine("⚠️ Warning: file exceeds 100 MB!");\n}, fileOption);\n\nawait rootCommand.InvokeAsync(args);\nRun it:
\ndotnet run -- --file somefile.txt\nIt already works. But this is just the beginning. Let's add some flair — colored output and a progress bar.
\n\nBeautiful output: adding colors and emojis
\nThe console doesn't have to be black and white. C# makes it easy to change text colors. Let's create a helper class:
\npublic static class ConsoleHelper\n{\n public static void WriteSuccess(string message)\n {\n Console.ForegroundColor = ConsoleColor.Green;\n Console.WriteLine($"✅ {message}"