On the weekend I spent some time on Safari reading “Smart Client Deployment with ClickOnce: Deploying Windows Forms Applications with ClickOnce” (Brian Noyes) hoping to get some answers to a really annoying problem (feature) in ClickOnce.
Microsoft’s new ClickOnce™ technology is marketed as being able to “radically simplify application deployment”. This may be so for deploying applications built internally and hosted on your own servers, but is far from the truth if your software is sold as a Commercial-of-the-Shelf (COTS) product that is usually deployed from servers hosted by your clients.
Noyes book is concise and explains exactly how and why ClickOnce works as it does, and how to overcome the obstacles to using it in today’s complex environments however, I would class it as a beginners guide to ClickOnce as it didn’t really delve into the problems and difficulties associated with deploying COTS products (or even products that require customisations to publishing methods and locations).
So, what are the difficulties with using ClickOnce with COTS products?
One of the “Security Features” of ClickOnce is “Tamper Protection” which uses digital signatures to protect the files in your application. When you publish an application with ClickOnce, you have to sign the deployment and application manifest with an Authenticode Class 3 Code Signing publisher certificate. This digital signature provides a guarantee that the manifests have not been tampered with since you published your application and also provides tamper protection for all of your application files. When your application manifest is generated, a hash of each of the files in the application is put into the application manifest along with the rest of the file information. When ClickOnce deploys or updates your application, it computes the hash of each file as it is downloaded from the server and compares the hash to the one embedded in the downloaded application manifest. Since the application manifest is signed and can't be tampered with to change the hash values for application files, there is no way for someone to tamper with any of your application files, because ClickOnce will refuse to launch your application if the application file hashes don't match after they have been downloaded.
This is a great concept; accept for the fact that at package creation time, you are required to provide details of the way the application will be published (i.e. HTTP, FTP, UNC, CD/DVD, Drive Letter) and the names of any servers used to publish the application. This information is then saved in the deployment manifest file which is signed during package creation (see where I’m heading with this!). Therefore, to be able to create a deployment package and sign it, you must know how your client is planning on deploying the software and the names of any servers used in the deployment process before the package can be created and signed. Now, I don’t know about you, but I know of no client willing to divulge all that information to a commercial entity so that it can be built into an installation package (I’m not even going to discuss what the implications are for clients wanting to change deployment methods and/or servers. Yuck!). Also, from a commercial point of view, this is not viable as you’d need to keep track of all this information so that it could be included in any future update provided for a client.
To get around this issue, clients can use a utility called Mage or MageUI (GUI version of Mage) which allows them to modify the installation package, re-sign it using your public key and then repackage it ready for deployment. Apart from the fact that this process is convoluted and very easy to stuff up (*See book extract below), we have now gone from a situation where we, as a supplier of the software, know what our package is doing to a situation that we have no idea what the client has changed which may cause the install or application to fail.
So what’s the solution? Apparently you can use the ClickOnce API’s to integrate the functionality of Mage into your own application thus limiting what the client can stuff-up (I mean change). How do you go about doing this? I have absolutely no idea as I’m still looking for resources on this topic. So in the mean time, I have reverted back to using MSI packages and getting the clients’ IT Department to deal with deploying the product. I’ll Endeavour to keep you informed of my research into the ClickOnce API’s.
* Extract from Noyes book explaining the manifest files: “There are two manifest files that are generated as part of the publishing process. The deployment manifest contains settings that affect how the application is launched and updated, and the application manifest contains settings that describe the composition of the application—specifically what files it contains and what permissions the application needs to run. Unfortunately, the file extensions selected for these manifest files and the way they show up in Windows Explorer can make it confusing as to which is which. The deployment manifest has an .application file extension, and is identified as an Application Manifest file type in Windows Explorer. The application manifest has an .exe.manifest file extension and shows a MANIFEST (all caps) file type in Windows Explorer. However, the ClickOnce documentation refers to these files as the deployment manifest and application manifest, respectively, so you will just have to get used to the fact that the .application file is the deployment manifest and the .exe.manifest file is the application manifest”.
Wow! Don’t know about you but that appears to be very confusing and would definitely leave some clients in a coma!