The Windows platform supports a number of different development frameworks (WinForms, WPF, UWP etc) and a number of different deployment models (xcopy, appx, msix etc). In this post we’re going to take a look at why the current trend for packaging Windows applications is a stop-gap, a temporary solution to the problem of application management on the Windows platform.
Installing an Application
Let’s start by looking at the basics of how users operate. When a user wants to install an app, historically they would have found the appropriate website where they could download it; they would then download the application (often ignoring the fact that it could be illegitimate and thus be malware/spyware/contain a virus). The next step would be that the user double-clicks on the downloaded file, which inevitably runs an installation process. At the end of the installation process, there may be an option to launch the installed application, or the user may be left to find the newly installed application in the Start menu.
More recently, users will open the Store (previously also known as the Windows Store or the Microsoft Store but it appears than it’s just called “Store” when you hover over the icon). They’ll locate the application they’re interested in (or not, since a lot of key applications are still not listed in the Store) and then they’ll click the Install button.
In both these scenarios there’s this magically step where the user has to “install” the application. For a user who isn’t a developer, what does installing an application actually do? is this something they want or need? does the user need to uninstall the application when they’re done?
Having been a developer for quite some time, I understand the history of installers and why we consider installing an application normal but is this pattern something we still need? The simple answer is that we do not need this and in fact is an unnecessary step that just confuses everyone.
So, what’s the alternative? Going back to what the user set out to do – they wanted to run a particular application in order to carry out some task. There’s probably not an easy solution (yet) to simply running an application that the user doesn’t have but what we can do is make the process of acquiring the application much simpler.
The condensed version is that the user navigates to the application’s website and clicks a button to download the application. Once the application has downloaded, the browser will attempt to launch the downloaded file. Since the downloaded file is an executable, the application will just launch – NO installation process, the application just runs!
Alternatively, the user navigates to the appropriate page in the Store and clicks the Run button – there’s a delay whilst the application downloads but then it launches without any installation process.
So, if the current process of installing an application is counter-intuitive, why is it that we have installers (MSI) and application packages (APPX, MSIX etc)? Let’s take a look at some of the reasons given and why they are no longer valid.
Single File Distributable
One of the supposed reasons that application packages exist is that it’s a way of distributing all the files of an application as a single file. This reason is trivial to debunk considering .NET 5 applications can be built into a single executable file (see this post for a break down of some of the options).
There is of course some heavy lifting that’s done in the background to enable the single executable to just run, but this is all hidden from the user – all they do is launch the executable and the next thing they know is the application running. No installation process.
The best thing is also the lack of any clean up, or uninstall, process. When the user is done with the application, it can just be dragged to the recycle bin or deleted.
It’s often touted that one of the benefits of application packages is that they, and in some cases their contents, are signed using a digital certificate. Prior to the installation process, the operating system validates the digital certificate and checks that the package hasn’t been tampered with.
Code signing has been around long before application packages and there is no reason for a single executable to be digitally signed. Windows can use this certificate to verify the integrity of the executable and validate the signing certificate, before allowing the application to run.
One of the biggest improvements to the security model of applications running on Windows was the introduction of identity. The identity of the application is used to determine what capabilities an application has. Where an application requests permissions (eg access to camera), the user will be prompted either at installation, or at runtime, to approve the permission request.
Without an installation process, you might be suggesting that there’s no opportunity for the user to review and approve access to capabilities. However, this clearly isn’t the case.
There’s no reason why an application can’t have an embedded manifest that defines the identity (and the required capabilities/permissions) of the application. When Windows launches the application it can extract the identity of the application and determine whether the user has granted permissions for the application – on first run, if additional capabilities/permissions are required, the user would be prompted at this point.
Given the identity is embedded in the application, if the file is moved or copied, the capabilities/permissions granted by the user would persist, avoiding the need to repeatedly prompt the user each time they launch the application.
Start Menu and Installed Programs
The package manifest file also defines various icons and attributes of the application that determine how the application appears on the Start Menu. Again, this information can simply be embedded in the application executable.
Let’s return for a minute to the scenario we painted where the user downloads the application and runs it (i.e. without an installation process). If the user comes back a week later, do they need to search the file system in order to find the application in order to run it? This is the purpose of the Start Menu, to provide a mechanism for the user to easily find applications that have been installed.
Again, why do we need a cumbersome installation process to do this? When the application is run for the first time, since Windows knows it’s the first time it’s been run (see previous section where it checks the application’s identity), the application could automatically be added to the Start Menu. If the application is moved or deleted, Windows should be smart enough to be able to update the Start Menu accordingly. Similarly, right-clicking on the application icon in the Start Menu should give the user the option to delete the application (not uninstall it!).
The application could also be added to the list of installed programs (the “Apps and Features” area in Settings). Whilst the application hasn’t technically been not installed, adding the application to this list would make it easier for users to manage the applications on their computer.
The Windows platform has a very sophisticated system for handling application resources. If you’re not familiar with how Resource Management works, it’s worth reading the documentation and specifically how you can Tailor your resources for language, scale, high contrast, and other qualifiers. Of course, with a single application executable one option is for all these resources to be embedded. However, this will significantly increase the size of the file.
Another alternative, which is already supported by application packages, is that resources are bundled in separate files that can be distributed alongside the application.
This then introduces the issues of how to publish applications that consist of multiple files to the Store, or to a self-managed deployment endpoint (similar to click-once deployment). Again, this problem has been solved for appx/msix through the use of appxbundle and appxupload files – these are essentially zip files used to collect the relevant files together so a single file can be uploaded to the Store. This same approach could be used for the purpose of publishing an application to the Store.
We’ve examined some of the reasons why application packages exist today and I hope you’ll agree with me that with a bit of extra effort by Microsoft we could go back to simply having application executables that can be deployed via xcopy, whilst retaining all the benefits of application packages.
One of the interesting side effects of not having an application package, is that we can go back to using configuration files to customise the behaviour of the application. For an installed application, there are mechanisms to access the contents of the application package. In the case of an application that is not installed, the same mechanism could be used to permit the application to access (read-only) the contents of the folder where the application is launched from.
In addition, if the application wanted to allow the user to dynamically control aspects of the application (i.e. override the behaviour defined in the configuration file), the new configuration information could simply be written to AppData. When the application is launched it would load the configuration file and then look in AppData to see if any of the configuration information has been overridden.
The really nice thing about configuration files that sit alongside the application is that when you copy the application (for example to another computer, or to an external harddrive), you can copy the configuration file with it.
In this post I’ve presented a model where we could abolish installers and application packages. The current model of application packaging is simply a band-aid solution to challenges presented in distributing and in verifying the identity of applications. Installing an application is a dated approach that goes back to when applications were distributed over several floppy disks and had to be installed before they could be run – this isn’t a workflow that makes sense.