Some Reasons why Installers are a mess

The other day, I was kvetching about installers (if you’re new here, I do that. A lot. You get used to it) and got an interesting reply on twitter:

Installers should be a 100% solved problem these days. Use a freakin’ msi on Windows, and use a pkg on macOS and all will be right with the world. Do not use bloated Java-based installers. Yes, I’m looking at you, InstallAnywhere and whatever they use (used to use?) for Archicad.

So the thing is, yes and no. Installers are, as this person said, something that should be solved, but it is not, and the problem is far, far worse on Windows, even if one uses MSI’s, than it is on macOS. Like far worse, for a variety of reasons.

First, and this exists regardless of platforms, outside of a very small number of companies, the amount of care put into installers is basically none. It’s scutwork, it generates zero direct income, it’s the first circle of hell for interns, etc. One of the best reasons for drag and drop installs on macOS is that it literally avoids installer executables.

The problem with this is that an application that has unit tests galore, UI/UX research by the pound, endless resources devoted to making sure it runs in a way that makes angel sing gets installed by executables that take all that and shove it into some of the most awful UI with almost zero testing on anything but the programmer’s machine. (I have literally dealt with installers that had hardcoded paths to the dev’s machine in the config files. More than once.)

It is also a place where the worst sorts of unnecessary cleverness lives, especially if we’re talking about high-end applications that have roaming license servers. In some cases, I have seen installers for Linux servers that:

  1. Require manual undocumented hacks to install on RedHat
  2. Don’t have a command-line option, so the only documented way to install is to install a GUI. On a Linux server. To install software. Shoot. Me.

There is no realm of software that can begin to touch installers for sheer, mind-numbing WAT. The things I have seen…

But even if you do things “the right way”, there’s a lot of problems. I’m going to talk about Windows here, because it’s…well, honestly, it’s easy.

First, MSIs are not a magical end-all. For example, I have seen MSI over MSI that has to be run as an admin, but if you’re not physically logged in as an admin and double-click on the MSI, you’re never asked to elevate to run the installer, it just fails with a mostly-useless error message. This is a trivial thing to avoid, and yet it happens a lot. I’m pretty sure I know why, the one dev building the installer logs in as an admin, so this problem doesn’t exist for them.

Sometimes you get a “you need to be an admin, start over” dialog. Thanks a pantload Chet, you could have handled this as part of the install. But you didn’t, and now you suck.

You end up getting really good with running msiexec from administrator PowerShell windows after a while.

MSI has a fairly standard set of switches for quiet installs, etc., but a lot of MSI installers don’t always use them all for some reason. So the install either fails, (sans logging, and logging on Windows is awful) or it runs in default mode with nary an error message to be found.

Did I mention installers are regularly awful? Because they are. Autodesk for example, has arbitrary filename length limits for its installers. That it regularly violates. Let me say that again, the company that sets the rules for how long a filename can be to work with its installer names files that break that rule. Not filename and path, just the filename. Make it make sense.

But even if you don’t hit that kind of nonsense, even if the MSI is perfect, then there’s the library issue. Also known as the endless strings of VC++ and .NET runtimes that have to be installed, often in a specific order, and when you uninstall, those stay behind, because if some other app is also using it, (and you have no way of knowing this), then removing it breaks other things, often, again, with no useful error message.

This is one place where the package format macOS uses is literal brilliance, a brilliance I did not truly appreciate until I had to deal with Windows deployments again. In some cases, we’re talking about nine or more separate MSIs that have to run in a specific order before the actual installer for the app you want to install can run. None of these will be visible to the user in Settings or the Control Panel. So when you “uninstall” the application, you’re only uninstalling the actual application, not the n things that were actually installed. Because there’s no safe way to do that in Windows.

On macOS, you just shove all the libraries in the application bundle and you’re good to go. For example, Adobe Photoshop 2022 has 121 frameworks, 8 “required” plugins, 52+ other “required” pieces of code and image files, and hundreds of various localization files. All of them are in the application bundle. There’s some other things outside in the Application Folder, some config files in ~/Library/Application Support/Adobe, some in /Library/Application Support/Adobe, and really, that’s mostly it. Compared to how things work in Windows, that’s almost nothing.

There’s also, on Windows, no good way around it. The architecture of the OS forces you into doing stuff like the VC++ redistributable/.NET Runtime dance. You don’t have a choice, because you absolutely can’t make assumptions about anything. Linux is literally more predictable than Windows.

However, that being said, there’s ways to make things easier.

  1. Fully support deployment tools, and no, I do not mean your weird .hta file. I mean SCCM/Intune/MEM, or other managed deployment tools. Out of the box, with support documentation. Autodesk is particularly good here. Solidworks is particularly not good here. If you create the software, it’s your job to make it work with managed deployment tools. Not the IT department’s, not the VAR’s, yours. If you cannot actually test with any deployment tools, then at the very least, do the work so that your installer can be slotted into said tools without weird dances, and undocumented tricks.
  2. When you uninstall, clean up after yourself as much as possible. You can at least delete the application folders. That’s not too much to ask. Mathsoft is a rather annoying offender with this one.
  3. Make it easy to slipstream/update your deployment point. I should not have to build a new deployment point from scratch just to add a .x update file to it. Yes, it’s not zero work. It’s more work for me when I have to push that out to a few thousand machines, and I should start charging consulting fees for ISVs that make this harder than it should be
  4. If on Windows, use the registry as sparingly as possible, and for the love of christ, do not put application-level variables needed to run the app in the user-specific hive. Deployment tools don’t run as a logged in user, doing stuff like that adds a lot of work to deployments. There’s no good reason to do this, stop it.
  5. Avoid environment variables. Those suck to manage outside of your installer.
  6. Document your installers and the process in excruciating detail. Seriously, we don’t mind.
  7. Virtual machines are literally free. It costs only time to test your installer basics. Do that.
  8. If your installer doesn’t work perfectly smoothly in fully manual mode (manual double-click on the installer file), it is not ready to go. Periodt.
  9. If there are multiple post-install steps that have to be done before the installer quits, those aren’t post-install steps. Those are installer steps. Automate them as much as possible. Don’t pause things just so I can click “next”. If I have to click next to finish the install, then just assume “next” will always be clicked, and bake those steps into the installer. Don’t make people click when there’s no real need.

FInally, the installer is not only code, it is the first code your customers will run. Why do you want them to hate you that fast?