Deploying Desktop Applications

Over the last couple of weeks I’ve been re-examining the desktop deployment strategy we have for Aderant applications. This installer navel gazing has resulted in augmenting our existing ClickOnce based approach with an MSI. The next couple of blog posts will drill into my ClickOnce headaches and my embracing of WiX to create MSIs.

Desktop Deployment Challenges

During the first steps into the new millennium, rich/smart/fat client applications which install binary files onto the local host fell out of fashion in the face of the centralized web deployment model. Deploying desktop applications was a delicate process: prior to the world of managed code, COM applications roamed the world and brought with them the plague of ‘DLL Hell’. Installing a new piece of software into a Windows environment could very well result in previously stable applications breaking, registries full of COM ClassIDs could become corrupt and the use of regedit and regsvr32 became almost accepted mainstream tools. The Microsoft .NET framework worked very hard overcome the fragility of the COM world but introduces its own complexities: managing versions, the global assembly cache, shadow copies and so on. Regardless of the technology, the software must be rolled out to each individual desktop and managed on each desktop. Installer technology supported the concept of repair but did not support automatic upgrades; additionally the installer often required administrator privileges to install.

A Mexican stand-off ensued: desktop applications allowed richer user experiences, a simpler programming model and the ability to run independently of a network connection; web applications have a much simpler deployment model and updates.

Of course, it is quite natural to want the best of both worlds and so various approaches have evolved to try to satisfy this, one of these approaches is ClickOnce.

Microsoft ClickOnce

As part of the .NET v2 framework, Microsoft introduced a new deployment option for desktop applications called ClickOnce. The goals of ClickOnce are to solve the following three major issues:

  1. Difficulty updating a deployed application
  2. Impact of the application on the users’ desktop
  3. Administrator privileges required to install apps

Conceptually, ClickOnce provides a central deployment model for desktop applications which does not require the installing user to have elevated privileges. It supports both the automatic repair and upgrading of applications and supports the use of an HTTP channel to distribute the installer. This last point is a game changer – desktop applications could now be installed and updated over HTTP on port 80, not requiring any additional firewall exceptions. This allows ClickOnce to be used to deploy applications over the internet as well as a corporate network. A couple of high profile, non-Microsoft examples of ClickOnce adoption demonstrates an industry acceptance: Google Chrome and Join.Me.

Corporate vs. Internet Installation

The ability to distribute software over the internet is something of a double edged sword should you choose to use ClickOnce to distribute software within a corporate network. The internet is untrustworthy, therefore mechanisms are required within ClickOnce to establish trust. These mechanisms are on by default and some cannot be switched off. To discuss some of these first requires an understanding of how an application is deployed via ClickOnce.

A ClickOnce deployment is basically managed by two XML files called manifests. There is an application manifest (.manifest) and a publisher manifest (.application). There’s the first annoyance – the application manifest does not have the .application file extension, which is so confusing. The application manifest contains a description of the files to be deployed and other settings that are controlled by the author of the application. The publisher manifest points to the application manifest, and contains information that is pertinent to the firm installing the application such as the publisher Url, update policy and the minimum required version. Each manifest is by default tamper proof, the manifests include a hash so that they cannot be altered without the use of appropriate tools such as the Manifest Generation and Editing Tool(mage.exe) – note: changing the application manifest invalidates the publisher manifest. It is possible to remove the hash from individual files within the manifest. The tamper proofing is only part of the trust story, you also need to be able to trust that the install comes from a trusted application vendor and that is was installed from a trusted publisher. Identity on the internet is established using certificates and so both of the manifests can be signed using a Code Signing certificate as evidence.

Time for the second annoyance… to install a ClickOnce application silently requires that both the manifests are signed using a certificate that is trusted as a software publisher by the machine undertaking the installation. This is a serious pain for ISVs. In our case, we can signed the application manifest with our company certificate and indeed should do so. However, if one of the manifests is signed then the other must also be signed, therefore the publisher manifest must be signed. The publisher of the application is the firm installing our software and so they must have a code signing certificate and ensure that the certificate is trusted by each desktop machine. If you choose to sign neither manifest, the installing user will see a security dialog window asking them if they trust the publisher and location – most corporate users will not know what they are being asked.

An additional step in the trust process is ensuring that the publisher URL belongs to the Trusted Site  (or Local Intranet Site) security zone of IE.

All of this protection makes sense for internet deployments but less so for intranet deployments within a corporate network which is implicitly trusted.

While the silent install is possible, if somewhat complex, a silent remove is not supported, the user will always be prompted to confirm the removal of the application. This single anomaly causes a great deal of frustration within the firms we provide software too. It is possible to achieve an automated uninstall but it requires the use of some nasty automation code:

On Error Resume Next
Set objShell = WScript.CreateObject(“WScript.Shell”)
objShell.Run “taskkill /f /im [your app process name]*”
objShell.Run “[your app uninstall key]”
Do Until Success = True
Success = objShell.AppActivate(“[your window title]”)
Wscript.Sleep 200
objShell.SendKeys “OK”

This VBScript snippet was taken from: The app uninstall key will be found in the registry:


Why am I so down on this? ClickOnce is a pull installation, it is expected that a user will choose to install the software. This is not so often the case within a corporate environment with a locked down desktop – applications are pushed to users using management software such as System Center Configuration Manager or via Active Directory group policies.

Additional Headaches

Beyond the heartache to perform a silent install and remove of the application, there are some other pain points of note.

ClickOnce and Citrix don’t mix well. ClickOnce permits installs by a non-privileged user, to do so the application is installed into the users local profile, this means on a Citrix environment each user has a separate install of the software taking up disk space.

The path of the application is a monster too, for example the Join.Me installer placed the files into:


If you have either long filenames or a deep file hierarchy, you can run out of characters for your file paths (260 character limit).

ClickOnce does not provide any extensibility points to run custom pre or post deployment actions.

In our particular case, we need to deploy assemblies to the application after the initial installation due to on-site firm customizations. ClickOnce does have a self-updating capability but we needed something more dynamic – more on this later…

In Defence of ClickOnce

This has been a rather negative look at ClickOnce so far so I do feel the need to provide some positive balance. ClickOnce is great at deploying apps over HTTP, it provides a self-repair and self-updating installer, it allows non-admin users to install software safely, it goes to great lengths to ensure the software you install can be trusted.

The case for ClickOnce was strong enough that we’ve used it for the Aderant Golden Gate desktop applications. The negatives are from unusual customization scenarios and field experience within corporate networks which has lead to the investigation into a MSI centric approach.

If you are pursuing a ClickOnce installer and need to dig a little deeper than the VS2010 template, I  strongly recommend getting Brian Noyes book:

In the next post, I’ll discuss our customization requirements that lead to using ClickOnce to install a bootstrapper.