I’ve recently had to integrate ClickOnce publishing of an application with an automated build and deployment process, and wanted to briefly chat about some of the headlines to watch out for if you need to do this in future.
There are two manifest files required for ClickOnce publishing - a deployment manifest, and an application manifest. The first very simple thing… the deploy manifest is named .application and the application manifest is named blah.exe.manifest. You might be tempted to think that the .application file is the application manifest, but not so.
The project I’m working on has multiple environments that we deploy to, and we’re distributing and updating the ClickOnce application from a website. This means that the deploy manifest can only be generated once you know the environment that you’re deploying to, as it contains the URL to check for updates etc.
In addition, the manifest files have to be signed before the ClickOnce application can be downloaded and installed. This means you have a choice…
- Either you have to generate appropriate manifests upfront for each environment that you might wish to deploy to, and sign each. This would occur while packaging up a release
- Alternatively, you have to ship the pfx certificate for signing in the release package, then generate and sign the manifests once you know which environment you’re deploying to as part of the installation
The second option is a little more flexible, but requires mage.exe (from the Framework 2 SDK) to be available on the install machine. In addition it means the signing certificate is kicking around in the release package, so obviously this is only appropriate for server software where the release and install setup is secure. I do have other justification for why I think this is ok - ask if you’re interested.
There are 2 msbuild tasks available to create the manifest files - GenerateApplicationManifest and GenerateDeploymentManifest. The task provided to sign a manifest takes a certificate thumbprint, which ties up to a cert in the local certificate store. This is not particularly useful, so it’s easier to write a lightweight msbuild wrapper around the mage utility, which can sign a manifest from a given pfx file. An example would be… mage.exe -sign ManifestName -CertFile PfxFilePath -pwd PfxPassword. If you want to generate the pfx to use in signing, take a look at makecert and pvk2pfx.
Be very careful about sequence - you need to generate the application manifest, sign the application manifest, then generate the deploy manifest, and finally sign the deploy manifest. If you generate both the manifests, then sign both, the publishing will fail. Basically the deploy manifest contains the public key token from the application manifest, so the application manifest must be signed prior to generating the deploy manifest.
Unless you need them, you don’t need to worry about the bootstrapper (setup.exe) or the versioned subfolders generated if you publish manually. The main thing is to have the deploy manifest pointing to the current version.
I also found the generated webpage for hosting the application to be quite bloated, so wrote my own. All you need to do is provide a hyperlink to the .application file, and clicking will trigger the ClickOnce runtime to download and install the application.
Phew. Think that’s it for now.