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:

  1. 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.
  2. Packaging format is just a folder of many files
    ClickOnce 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.
  3. 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.
  4. 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.
  5. Other niggling limitations customers don’t like
    None 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.

  • http://twitter.com/gringod Adrian Ritchie

    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’.

    As for how you switch over, I’ve just published a blog about that: http://blog.sourcetreeapp.com/2013/05/13/new-installer-updater-for-sourcetree-for-windows/. It’s not automatic, although people who haven’t switched by the time that the new installer leaves the ClickOnce install behind (0.9.3+) will get a prompt at startup explaining that a new installer is available, and will link to the download.

  • Pjcast

    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