All Posts

A complete archive of all 32 blog posts, organized by most recent.

Introducing OpenCLI

About three years ago, I was invited to meetings with the System.CommandLine team at Microsoft. They were in the process of finalizing System.CommandLine and wanted input from people in the community, and I was included due to my work on Spectre.Console and Spectre.Console.Cli.

Building an iterator in Swift

As part of learning Swift, I decided to port my project Spectre.Console (written in C#) to Swift.

Intellisense for your GitHub Actions workflows

Although I'm a big fan of GitHub, I'm not a big fan of YAML. When it comes to orchestrating my builds, I usually prefer some kind of build script, but bootstrapping that build script is a necessary evil so we're stuck with YAML for that part.

Thank you Octopus Deploy!

When I started working on Cake in 2014, I did it to scratch an itch I had. FAKE existed (which has been a tremendous initial inspiration), but I didn't know F# enough (at all) to be confident enough to bet our build process on it.

Enumerating monitors in Rust using Win32 API

I had to enumerate all monitors yesterday using the EnumDisplayMonitors Win32 function, and I thought I would write a couple of lines about what I did since I couldn't find any useful information about how to do this.

Targeting ARM64 for Windows in Rust

I wanted to run a thing I'm building with Rust on my Surface Pro X which is an ARM64 device the other day. My initial thought when I got the idea, was "I hope it's not complicated to do".

How to create .NET Core release artifacts with GitHub Actions

In this blog post, we'll create a GitHub Action that triggers each time a release is published, builds a binary on three different build agents (Windows, macOS, and Ubuntu), and attaches the compressed artifacts to the release.

How to write a stateful Roslyn analyzer

I wrote a stateful Roslyn analyzer a couple of days ago to analyze the codebase at work for irregularities, and I thought I would share my findings on how I did it.

Testing stuff with Windows Sandbox

Last week I decided that I wanted to try the new version of Windows Subsystem for Linux (conveniently named WSL 2). WSL 2 requires that the computer enrolls in Windows slow ring, and since the computer I was on didn't receive any insider builds at all, I went ahead and enabled the slow ring. The update started, and I went to bed.

Roaming profiles with Windows Terminal

If you have more than one computer that you use, you might have noticed that it requires some work to keep your Windows Terminal profile up to date.

How to find a NuGet package path from MSBuild

Lately I've been porting some projects at a client from .NET Framework to .NET Core, and as part of that I had to convert csproj files from the old project format to the new one. That means getting rid of package references in packages.config and replacing them with PackageReference elements in the project files.

Debugging an UWP store app with WinDbg

I was encountering a rather irritating bug a couple of days ago that only manifested itself when built via the native toolchain in release mode. I couldn't get it to manifest itself when running from Visual Studio for some reason and the problem occurred so early in the app's lifecycle that I didn't have time to create a minidump of the process.

Using build counters in Azure DevOps

We recently migrated some builds from TeamCity to Azure DevOps at my client, and couldn't find a feature analog to TeamCity's %build.counter% which we've been using to get automatically incremented version numbers for artifacts.

Generating API clients using AutoRest

This blog post looks at automatically generating an HTTP API client from a OpenAPI specification (formerly swagger) using AutoRest.

An introduction to Spectre.Cli

I've been writing a lot of CLI apps, both at work and in my free time, and there's never really been a command line parsing framework that has fitted my needs. While being either too complex or too simple, it's always nagged me that I need to write so much code myself. What I wanted was a way to be declarative about my commands, options and arguments while still allowing composition of them.

Debugging Rust on Windows using Visual Studio Code

I recently wanted to debug a Rust program on Windows that I had written, and was struggling with how to get it to work. Since there was quite a lot of hoops to jump through to get it to work, I though I should share it with other people as well. I've written this blog post from memory and I'm far from an expert in LLVM or Rust, so if you see something strange here then let me know.

Calculating product versions for MSI packages compatible with semantic versioning

In my new project Jarvis I wanted to start generate preview versions of the MSI packages, but one problem with that is that MSI requires the product version to be in the format Major.Minor.Patch which isn't compatible with semantic verisoning. We CAN use the Major.Minor.Patch.Revision format as a product version, but that won't work with major upgrades. An example of this would be 1.2.3-alpha45 which would require a different version number than 1.2.3-alpha46.

Binding to a RichTextBox in WPF

I've been doing some WPF development the last couple of weeks, and one thing that bugged me was that there is no way (as far as I know) to bind content to a RichTextBox. This makes it kind of difficult to follow the MVVM pattern since the view model needs intimate knowledge of the view.

Conditionals in XAML

Ever wanted to display things conditionally in XAML based on a pre-processor directive like `DEBUG`?

Using embedded resources in xUnit tests

I was reading Andrew Lock's excellent blog post about Creating parameterised tests in xUnit when I remembered something I wrote a while back that has proven to be quite useful.

Azure Web Apps and the certificate store

I was trying to load a certificate from the certificate store in an Azure Web App today, and for some reason I could not find it via it's thumbprint. Since I thought I was looking in the wrong certificate store, I went to Kudu to take a closer look via the PowerShell debug console.

Script aliases

Cake supports something called script aliases. Script aliases are convenience methods that are easily accessible directly from a Cake script. Every API method in Cake is implemented like this.

It's not a party without Cake

I have during my nine years as a (professional) programmer used several different build automation systems such as Rake, psake, CMake, TFS Build and FAKE, but none of these have allowed me to write my build scripts using C# - the language I use the most.

The singleton logger

It is widely accepted that you access logging frameworks via a static singleton instance, and most logging frameworks are designed to work like this. But why? Many people often refer to it as being a cross-cross cutting concern; and that it's therefore not important to do things by the book. Not only does most logging frameworks use the static singleton as a façade, but they also store process-wide state.

Introducing Lunt

Last summer, a friend and I started to write a little Paradroid clone. Since my only real experience as a game programmer was with XNA and MonoGame, I had grown fond of the XNA Content Pipeline, and naturally wanted something similar for this project.

Displaying TeamCity build status on GitHub

Have you ever wanted to display the current CI build status for a TeamCity project in your GitHub README? I did but couldn't find any good, straight forward information about how to do it. Turns out it's quite simple.

BinaryWriter and C++

A while back I had to read string data written by .NET's BinaryWriter in C++. I was initially a little bit confused about how the data was written but after using Reflector it turned out that the write method prefixes the string with a 7-bit encoded integer.

Culture agnostic string comparisons

Something I've seen a lot at different clients is naive string comparison. The most common case is to do something involving String.ToLower() on both strings that are being compared and then an equality comparison of the result.