Friends don’t let friends use ClickOnce

I’ve had a fair amount of experience with Windows-based installers in the past, including non-Microsoft Installer based systems like NSIS and the open source WiX, but most of the time I’d been working with one-off installers for native code projects, like the Ogre3D SDKs. I pride myself in not pre-judging the best toolset to use for any given problem – which is why I switch languages a lot – so when I came to write SourceTree for Windows, which is based on .Net, I checked out the landscape again.

I discovered that ClickOnce was Microsoft’s recommended approach to .Net application deployment , and had the advantage of including both the installer tech and an auto-update system, together with Visual Studio integration, a simple deployment model and so on. I’d seen it used on a couple of other products, and during testing both internally and with our batch of beta testers all seemed to be well, so that’s what we went with for the release.

Hindsight is a wonderful thing, and it turns out that ClickOnce has a number of problems which only really show up when you use it at scale, by which time it’s a bit too late and you can find yourself with a lot of support requests. Here are some of the issues:

No support for proxy servers
It turns out that ClickOnce just doesn’t work at all with secure proxy servers which can’t authenticate automatically. It also turns out that a lot of people have this kind of setup. There’s a (nasty) workaround for the auto-update system, but this can’t work for the first install. Microsoft have known about this problem for some years, but have decided not to bother fixing it.

Packaging format is just a folder of many filesClickOnce puts all of its files in a folder per version and just tacks ‘.deploy’ onto the end of each. Simple, but it has many problems:

Some corporate firewalls will detect that some of those files are executable binaries, and will flag them as dangerous. Some will totally block the file making the install/update fail with a download error, some will ‘sanitise’ the file and send that on, making the install fail later with an ambiguous hash mismatch error.

If you use a CDN to distribute your installers, distribution of many files is very difficult to make atomic, potentially leading to temporarily incomplete results being visible

Having the download (first install and update) as a multi-file affair makes failures due to interrupted connections etc much more problematic, vs just resuming the download of a single package.

You can’t separate the update metadata from the update itself
That is to say, ClickOnce forces you to use a single URL for both the metadata where it finds that there is an update, and where it gets the actual update from (the installation files are in a subfolder). This might seem sensible, but in practice it’s very limiting. If they’re separate, you can point the metadata URL at a location which you can update in-place and which will never change, and you can put the update files themselves wherever you like (a CDN usually). ClickOnce forces you to put both in the same URL, which is limiting when it comes to reorganisation, and also it can mean you have to put the metadata on the CDN too, and CDNs don’t often like files that update in-place. It’s just an awkward and inflexible system.

Random weird sh*t in a small percentage of cases
We’ve found over the last couple of months that occasionally a user’s machine refuses to install or update despite the ClickOnce installer being fine for everyone else, and in circumstances that were not explainable by the other issues listed above. It’s not that common, but even if it’s only 0.5% of cases the numbers were starting to add up. We often managed to work around the problems manually, but it’s just not something you want to spend your or your customer’s time on.

Other niggling limitations customers don’t likeNone of these are deal-breakers in their own right, but combined with everything else they’re worth mentioning:

You can’t choose where to install the product – ClickOnce chooses an esoteric location for you

ClickOnce’s reliance on the logged in user means you can’t install once for everyone on a PC, or distribute a bulk install as admin

No offline installer – while you can zip up the deployment it didn’t work for everyone

So, all these things have been building up , tempered with workarounds but nevertheless a constant thorn in our side. In the end, we had to make the call that ClickOnce just wasn’t salvageable as a deployment tech to use at scale. Instead we’ve moved to a standard Microsoft Installer based tech stack, using Advanced Installer to build the installer and the update system. I really liked Advanced Installer because not only does it address all the issues above, it saved me a ton of time over building something myself with WiX (and having to solve the prerequisites bootstrapper and auto-update system), and was also just complex enough to do what I needed; it’s a pro tool but doesn’t require 3 months training to master it, you can pick it all up in a few days.

I wrote this blog post because it’s what I wish I’d been able to read before I decided to use ClickOnce. It’s one of those technologies that looks fine on the surface and in limited testing but then reveals a bunch of horrid edge cases and random unreliability issues in the wild, just when you don’t need it.

From my experience with ClickOnce it seems to be designed and works fine within a single organisation but once you get beyond that it all starts to fall apart.

As for SourceTree, if I’ve installed that with ClickOnce do I need to do anything to now get the Advanced Installer auto-update system?

Patrick Kooman

Patrick Kooman

Nice overview of the potential pitfalls of using this technology. No offence intended, but do you know the main reason for ClickOnce? It is my understanding that ClickOnce is mainly here to support non-admin users, which is common in corporate environments.

ClickOnce applications are basically sandbox applications (that’s why the esoteric location and no install-for-everyone), where the default security zone is either internet or intranet, depending on the location from where the client/customer runs it.

Except for the ability to update itself (handy!), i don’t see many advantages in using ClickOnce for home users.

stevestreeting

Yep, and I considered the seamless handling of non-admin users to be of benefit for any application (that didn’t need to start services or other things). I could live with the inability to pick the install location, given that ClickOnce was integrated with VS and basically recommended by MS (with no particular context given on what it was poor at in their docs). In the end it was the unreliability that was the primary issue.

stevestreeting

The thing is, I don’t even think it’s particularly useful for corporate environments, given that it can only install in the user’s home directory. Assuming that corporate shops are most likely to want their PCs to be a stock install not specific to any user, ClickOnce doesn’t seem very useful there either. It’s one of the reasons I thought it was designed for end-user install setups, which is how a lot of developers work. But it’s not very good at that either; frankly I’m struggling to see what it IS good at, other than appearing to be convenient (VS integration) and ‘standard’.

Yeah, click once has so many problems and Microsoft hasn’t bothered to fix many of them. One serious issue, which is probably still the case, affects systems that rarely reboot.

If you happen to update a click once app, and then your system shuts off uncleanly (power loss, etc) before a reboot, your whole click once registry entries/disk location gets corrupted. Updates and reinstalls just fail. With no clean way to fix. You think they would sync any pending changes… But nope.

Not a reliable installation system.

Kamron Brooks

I’m having the 4th problem with a program I want to install can you please detail some of those work arounds you mentioned?

stevestreeting

Sometimes completely uninstalling and reinstalling fixed it, sometimes it required a complete rebuild of the ClickOnce system (deleting all the metadata, meaning ALL ClickOnce apps needed to be reinstalled, not to be done lightly). The best workaround is to stop using ClickOnce.

Kamron Brooks

That’d be great, except I’m the “client” in this case not the developer, who’s saying I should reinstall windows. Any way to avoid that? Reinstalled .Net 3.5, 4.-whatever, repaired, cleared caches….

stevestreeting

You could try deleting the %USERPROFILE%AppDataLocalApps folder and then re-installing any ClickOnce apps you have. However you may sadly be in the ‘limbo’ state that ClickOnce occasionally seems to get itself in so if that doesn’t work you may be stuck. I’d advise suggesting to the developer that it would be worth investigating alternatives to ClickOnce for future releases.

Gian

ClickOnce is more or less the .net version of Web Start for Java.. also with this last one i had bad experiences, at end user side. Installations that don’t start, updates that are not performed and so on.

With Microsoft Installer and ClickOnce i think that what is performed behind the scenes by these systems is a LOT more complex than what an installer should do, even just looking at the ammount of things you need to know/configure to create an installation. Normally they should just copy some files, see if the operating system has some libraries installed, check if there are older versions of files and update it and so on.. but when i had to generate or run an InstallShield MSI based installation it always took ages to complete the task.

After some time i switched to NSIS, with just launching the .net runtime at the end of the installation i forgot all the headaches of the past

I had also experience in having to run/install a Java software from the browser and instead of using Web Start i tried GetDown, that is an applet based installer (but probably works also locally) that performs also the update of files already downloaded by previous runs (based on the hash code from the file). It’s quick, simple and reliable (it is used by some Java based MMORPGs that usually update files almost every week)

Something similar for .NET software, would be good

Do you think that in the (far) future all the software would be managed by centralized appstore/market/etc system and today installations will be deprecated?

stevestreeting

I hope not – my experience with app stores is that they can be a PITA sometimes. I hope we always keep direct distribution as a viable option.

giammin

completly agree. and you did not talk about the pain of mantaining an application database between updates

Nicola Eusebi

Hi Steve, thanks for the post!

I’m currently using ClickOnce on a .Net application and it was doing good until it started to randomly give a “system.argumentexception value does not fall within the expected” to some users. Have you ever stumbled on this problem? I’ve been unable to solve it so far, also because I have not been able to reproduce the problem on my computer.

I also have another question for you, what alternative to clickonce would you suggest?

My needs are:

-Simply copy some dll’s and an exe into a folder;

-manage automatic updates;

-Something that is simple to learn and manage;

-Possibly something free or quite cheap

Thank you in advance.

Nicola

stevestreeting

This was one of the many random errors we had reported with ClickOnce, and you’ll find it widely reported in many ClickOnce installs on StackOverflow etc. A few users found that uninstalling SourceTree completely, rebooting, then reinstalling fixed this but it didn’t work for everyone. One of the reasons we ditched ClickOnce, when you scale it up to lots of external users it just has too many rough edges to support properly. I get the impression it was only designed for use in internal office deployments.

We moved to Advanced Installer and have been very happy with it. When I used to write graphics software I used to use NullSoft installer which is of the ‘just a script to extract files & run some scripts’ form, and I liked its simplicity; the trouble today is that since Microsoft moved to merge modules for shared system components, Microsoft Installer is the only thing guaranteed to work properly & MS discourage ‘old skool’ installs now. You can run external MSI installers for merge modules / dependencies but they’re never quite as integrated as I’d like. Plus, if you ever want to be able to support automated network deployment by admins, you have to really go with something MSI compatible for group policy support. So it depends what you’re installing and what the audience is.