Distributing Windows applications

This article presents all necessary steps to get your Windows (desktop) application into the hands of your users. I list and compare 13 installer builders which package your application as a setup, discuss distribution options such as package managers, and present solutions to integrate automatic updates and licensing into your application.

Introduction

If you are an application developer of a Windows desktop application (GUI or CLI), you need to solve a few problems:

  • Packaging: How do you package your application? Do you offer a portable app compressed in a zip archive, or package it in an installer (setup)?
  • Distribution: How do you distribute your app to your users? Do you put the installation package (or zip archive) on your website and ask users to download and install it manually? Or do you put into a package manager, like chocolatey?
  • Auto-Updates: once your users installed your application, how will they keep the application up to date? Is there a notification mechanism triggered regularly on the client, or do your users have to regularly visit your website?
  • Licensing: the ability to limit the spread of your application, by providing your users with license keys, serial numbers, etc. – the permission model might be very crude (e.g. a key is either valid or invalid), or very fine grained (e.g. where the key dictates that a few specific features of your application are disabled, but everything else works). There might also be dependencies between the license key and distribution / auto-updates, e.g. a license key that offers free auto-updates only for minor version updates, or only for a specific time period.

The following sections will provide pointers that help you answer these questions. This article is not a detailed tutorial, but rather a high-level overview of your choices and available technologies.

Windows install builder technologies

The very first problem you need to solve is packaging. While very simple applications may get by with just bundling everything in a zip archive (“portable app”), it is more common and user-friendly to offer an installer, sometimes also called setup. The installer configures shortcuts to your application (e.g. on the desktop or in the start menu), copies files to various places on the user’s disk, and provides an uninstaller to cleanly remove your application.

To create such installers, there are products called install builders, setup builder, or similar, which support developers with creating installers. Install builders are typically GUI applications that let you define the files to package, the menu entries you want created, allow you to define registry keys, and much more.

Before we get into a comparison of install builder products, let’s understand which three basic installation techniques exist.

Exe-based installers

Exe-based installers (e.g. setup.exe) are regular programs. They perform the necessary steps to install your application. This includes copying files, registering DLLs or services, manipulating the registry, or setting up an uninstaller. Typically, there is a sequence of dialogs windows (sometimes called “installation wizard” or “installation assistant”) which guides you through the necessary steps.

MSI-based installers

An MSI file is a container format whose content is interpreted by Windows Installer (msiexec.exe). Windows Installer is present on all modern Windows installations by default. Back in the day, it was only used by Microsoft to install and update their own applications (such as Windows update packages), but it is now in active use by third parties (like you) to create installation packages for their own applications. The MSI format specification lets MSI package authors customize a plethora of options. You can provide your application files and where they should be copied to, customize the dialogs (to a certain degree), manipulate the registry, run custom actions, and much more.

MSI installers have a number of advantages over exe-based installers. MSI offers a standardized installation (and GUI) experience, a very high robustness and it integrates better into the Microsoft ecosystem, e.g. Microsoft SCCM to run remote deployments. You can find a very good technical summary here.

Exe containers for MSI installations

Most MSI-based installer authoring tools let you create a wrapper .exe file which installs the MSI file under the hood. This is also called bootstrapping.

MSIX

MSIX (official docs) is an universal package format supporting Desktop, mobile and all other Windows 10 devices – in other words: UWP apps as well as traditional Win32 desktop applications. A MSIX package is just a zip package with your application files and some configuration XML files. A MSIX package can be uploaded to the Microsoft store, or offered as direct download (sideloading), e.g. from your website.

However, there are numerous limitations that apply to desktop applications (see here). For instance, MSIX packages are always installed per-user (not globally for all users), and are installed and started in unprivileged mode, disallowing your app to register or use any feature that require elevated (admin) privileges, or install a Windows service. Also, you cannot show any custom dialogs during the installation process.

MSIX packages must be digitally signed, which is either done by Microsoft if you transmit your app to the Microsoft Store, or you need to do it yourself, using a valid code signing certificate from a certified vendor, which does not come for free. MSIX supports auto-updating, either via the store, but also for sideloaded applications. See this article for a more detailed introduction to MSIX.

Install builder overview and comparison

The following table provides an overview and comparison of install builders, starting with free ones, then commercial ones.

The column Supports auto-updating indicates whether the solution assists you with:

  • Building small delta-updates, to speed up the downloading process,
  • Hosting the installers (and delta-patch installers) on your server, as well meta-data (or API) that indicate version updates,
  • Providing client-side applications (or code) to discover, download and install new updates from your server.

The column Handles licensing indicates whether the install builder lets you define a predefined set of license/product keys (or a generative validation algorithm) for your setup, such that users have to provide a key as part of the installation procedure in order to successfully complete the installation.

NameCosts / licenseSupported format(s)Supports auto-updatingHandles licensing
InnoSetupFree / OSSExe
NSISFree / OSSExe
InstallForgeFree / ProprietaryExe
WiXFree / OSSMSI
InstallBuilderCommercial / proprietaryExe
InstallAnywhereCommercial / proprietaryJava, Exe
InstallShieldCommercial / proprietaryMSI, MSIX
Supports building patch releases
PACE SuiteCommercial / proprietaryMSI, MSIX
Supports building patch releases
Advanced InstallerCommercial / proprietaryMSI, MSIX
Actual InstallerFree & CommercialExe
With ActualUpdater
Visual InstallerCommercial / proprietaryExe
AKInstallerMSICommercial / proprietaryMSI
Supports building patch releases
AKInstallerCommercial / proprietaryExe
Supports building patch releases

Given the large number of solutions, finding the right one is out of scope for this article. As with any technology, you should build a list of your requirements first, and then check how well each of these solutions can fulfill them. The key term here is “decision matrix”, for which you will find plenty of resources on the Internet.

If a hard requirement is that the install builder must be free, then Inno Setup is among the most capable solutions. It is much easier to use than WiX, is well documented, very mature, and has a large community. Its only downside is that you have to learn Pascal Script to write custom actions executed during the (un)installation. However, Pascal Script is a mercy, compared to the script language used in NSIS, or learning WiX.

Handling distribution, auto-updates and licenses

In case your selected install builder does not support auto-updating or licensing, or the provided mechanism does not work the way you need it to, you have two basic options: you can either buy a third party solution that solves this problem, or implement one yourself.

Distributing your application

To get your application on your user’s computers for the first time, you have a few options, such as:

  • Host the latest installer on your website (direct download)
  • Distribute your app using a package manager such as Chocolatey or Scoop
  • If you built an MSIX-based installer, distribute it via Microsoft’s Store

Auto-updating your application

The options I found are:

  • If you distribute your application via Chocolatey or Scoop, users can install updates using the command choco upgrade <appname> or scoop update <appname>. Thus, you just need to write a little bit of code where your app retrieves the manifest from the right repository, parses it, compares the version number with the version of your app, and if there is an update, make a PowerShell call to choco upgrade or scoop update.
  • If you built an MSIX-based installer, there is a mechanism that supports auto-updating your application (even for sideloaded applications).
  • Google Chrome Updater is a free and open-source solution to implement auto-updates, but it’s difficult to set up. Once you got it running, though, it is stable and hassle-free.
  • Squirrel is mostly designed for C# app developers.
  • WinSparkle is an easy to use solution whose functionality you can call from C/C++ directly, or from any programming language that supports importing DLLs and calling exported functions (e.g. Python using ctypes).
  • Actual Updater is a stand-alone application (where you configure the server URL with an ini file) which the user either calls directly (e.g. from the start menu), or from your app.

Licensing your application

There are solutions such as keygen, cryptlex or soraco which let you manage product/license keys on a server (including more complex policies, e.g. automatic expiration dates, etc.). Your application’s client-side code then needs to request the key from the user (e.g. via a prompt), and regularly validate it using the server’s API.

Implementing your own solution

Sometimes rolling your own mechanism which handles both auto-updating and licensing may be worthwhile. This is particularly true if your desired licensing model is not reproducible by third party licensing solutions. There might also be a complex dependency between your license and the auto-update mechanism, such as limiting updates for specific licenses to only include specific versions. Some of the solutions mentioned above do cover this, but the devil is in the details!

Conclusion

While developers expect that it requires a lot of effort to implement the functionality of an application, they often underestimate the work they need to put into distributing windows applications. You need to evaluate (test & adopt) an installer builder, and find an appropriate auto-update mechanism. This article only covered Windows, so be aware that efforts increase even more, because deployment mechanisms differ for each platform/OS. If you are a solo developer, that’s tough luck. If you are company, consider hiring a specialist, such as a release engineer, who will get the job done faster and better, thanks to prior experience.

Leave a Comment