ClickOnce is a powerful and easy-to-use deployment technology that offers a relatively hassle-free experience for the end user when properly configured. The developer story for ClickOnce varies from super simple to maddeningly complicated, depending on what you are trying to accomplish.

I recently wrapped up a project where ClickOnce was a large part of the release strategy, and also responsible for a lot of the headaches that went with it. If you use ClickOnce as it was intended, it’s remarkably effective. Knowing that most of you reading this article probably don’t use stuff “as intended” I’d like to offer you the benefit of my experience:

1. ClickOnce is a “non-impactful” deployment mechanism. This means you can’t do things ordinary installers can, like adding a new font, putting files in the GAC, or changing registry settings.

Keep this between us, but you actually can install a new font. It just requires a small workaround. In order to do this, you have to make your new font a pre-requisite of the ClickOnce app you are installing, and create a bootstrapper for it. You can do this by creating a setup project in Visual Studio that only adds your font, and then run the Bootstrapper Manifest Generator found in the MSDN Code Gallery, here: Once you have created this, you can drop it in the bootstrappers folder. Which, depending on whether you are running VS2005 or VS2008, respectively, looks like one of these:

C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\BootStrapper\Packages


C:\Program Files\Microsoft SDKs\Windows\ v6.0A \Bootstrapper\Packages

After you add the bootstrapper, select it as a requirement in your project on the Publish tab.

2. ClickOnce applications are installed per user, per machine. If 5 people use the same machine, each of them will get a new and separate install, and not necessarily all the same version.

There’s not much (anything) you can do about the multiple installs, unless you make your application web-only, but you can at least guarantee that they are all running the same version. The trick here is a two-parter: You need to make sure your application checks for updates PRIOR to running, and you need to set the minimum required version to your current build. Fortunately, both of these settings are located in the Application Updates dialog in Visual Studio.

3. ClickOnce isn’t exactly what I would call “Environmentally Friendly.” By that, I mean if you’re like most developer shops, your applications go through a series of environments (DEV, QA, maybe even UAT) before landing in Production. ClickOnce doesn’t move gracefully between these environments.

Often, moving an application from one environment to the next means tweaks to the Config files. Database connection strings and web service URLs are just a couple examples of what can change between environments. If you make changes to your Config files after the publish step, you need to re-sign them using Mage.exe or MageUI.exe and a signed key file.

4. Along these same lines, if you want to take the environment scenario to the logical conclusion, and have ClickOnce pull updates from different servers (such as DEV, QA, etc…) then you have another problem. There’s no obvious way to repoint a ClickOnce published build to a new Update URL. Mage.exe and MageUI.exe don’t provide this functionality.

Fortunately, you can change this without rebuilding and republishing your application. The setup.exe file that is generated by the publish process has some command line options as well. Typing setup /? at the command line reveals the /url switch, which you can use to change the update location that Visual Studio bakes into the setup.exe file. This URL is what ClickOnce checks for application updates. Use this with caution, since you aren’t just changing the target for the immediate run, but actually modifying the setup.exe itself.

5. ClickOnce is a control freak, by design. Most of the time, this is a good thing since it prevents people from maliciously tampering with your application after it has been published or deployed. Unfortunately, if your application has user adjustable options stored in the Config file, then you’re in for some heartache. ClickOnce applications won’t run if any of the files in the manifest have changed, even after deployment.

You have two options here. The first is to change your application so it doesn’t rely on Config file settings. As for the second option, I lied. Changing your application to eliminate this dependency is really the only choice if you want to use ClickOnce.

6. Mage.exe (Manifest Generator - command line tool) and MageUI (Mage with GUI interface) were not created equally. There are things you can do in MageUI.exe that you simply cannot do in the command line version. Unfortunately, this makes automation of the build and publish process pretty tough.

For example, if you need to add a file (or group of files) to your published application as the result of a secondary build process, this will require regenerating and resigning the manifest. In MageUI.exe this is a pretty trivial task, although it does require manual intervention. There is no equivalent functionality in Mage.exe, so scripting it becomes impossible.

7. ClickOnce applications and updates are published by posting them to the web (or fileshare.) There is no method or model for controlling who can download the updates or when.

If you have a large number of users, or bandwidth concerns, then you could be in for some difficulty when you post a new version of your application and 9am rolls around the next day, with 2000+ different people trying to download files at the same time.

8. ClickOnce only downloads the files that have changed since the last download. (Sounds good, right?) Unfortunately this determination is made by the build version of the file, not any hash or checksum value.

Some shops reversion all files with each build, even if nothing changed. While the merits of this practice are debatable, it does happen. If you are using ClickOnce to deploy your application, that means every change, however slight, will resulting in re-downloading the full payload, making scenarios like #7 above even more unpleasant.


Hopefully these tips and hints will illustrate what ClickOnce is and is not capable of and make your ClickOnce experience a little less frustrating.