Friday, June 22, 2007

Notes On ClickOnce Deployment

Microsoft's ClickOnce is a major leap in deploying client software applications. Unlike previous attempts that only dealt with one part of deployment, ClickOnce was designed to abstract the full installation life cycle; from the API and integrating with .NET in the System.Deployment.Application namespace and Visual Studio, to the development environment (Visual Studio), to the administrator, to handling automatic application updates, to rolling back to previous versions, and finally to repairing and removing the application. ClickOnce is truly the first step cutting-edge technology in client software installation, good job Microsoft.

ClickOnce: A deployment best practice
ClickOnce was well architected to handle client apps deployment in a best-practices way. So if you find yourself in some convoluted situations, it's time to review your deployment strategy instead of trying to do "hacks" in ClickOnce. Chances are, it will fit with ClickOnce best practices. For example, ClickOnce doesn't support setting up Desktop shortcuts because this habit proved to be a cause of more nuisance than help to users. Even research shows that users don't like apps cluttering their desktops with shortcuts. Plus many more disadvantages to this practice and this post is not the place to flesh them out.

About this post
This post is not for for the ones who are already familiar with ClickOne. If you're not familiar with the basics of ClickOnce, then do a quick search on Google and you'll get plenty of info. This post is for the ones who are stuck on some sticky issue with ClickOnce that hasn't been well documented or commented on at the time of this writing. All the answers I present here come from first hand experience with ClickOnce where I've personally tested every statement I made. The below statements are valid for .NET 2.0 framework and Visual Studio 2005.

  1. Once an application is deployed, you must not touch any deployed application files. The deployment files are usually signed. So any attempt to modify them will break the signature and produce an error in installation. If data must be modified such as connection strings then ClickOnce allows for this too. Read more about this point further down.

  2. The "secret weapon" of ClickOnce is its DataDirectory property. The cool thing about local Data directory is that it is maintained across different versions. So user specific settings are preserved when they upgrade to a new version. It is only preserved if the user makes local changes to the data file. If not, then the latest data file for the new version is downloaded. All versions read from the central same local data source. Even if you rollback to a previous version, the most recent local data for the latest version will be used. The way ClickOnce does this is by simply replacing the old DataDirectory path with the new one. In a nutshell, the latest user modified settings are guaranteed to be preserved across versions. No more worrying about how to preserve the local settings of previous versions. How cool is that?

  3. Rolling back to older versions is a breeze. An admin can switch on the fly to any version by simply renaming the _.application to .application in the deployment directory.

  4. How to get the application deployment directory path. One should not need to programmatically know where the application was installed from. If you find yourself needing that, then most probably, you’re approaching your problem from the wrong angle. However, if you still think you do need this URI, the only way to get the location of the deployment share is by using the CurrentDeployment.UpdateLocation member. The others are always null for some reason in this version. Most of the CurrentDeployment members are null. The only ones I found to be working were the DataDirectory and the UpdateLocation members.

  5. Admins can easily modify the deployment settings. An admin can edit any of the deployment settings (all that’s available for the developer from VS 2005) using the MageUI.exe (GUI) or Mage.exe (Command prompt) tool that comes with the SDKs. However, the admin would need to sign the changes with a certificate (any certificate installed on the machine will do) before saving, for the new settings to take effect. For example, the admin can install two editions of the same app to different share names side by side. The cool thing is that a new shortcut will be added pointing to the new edition and grouped under the same company name! This is ideal if one app needs to be in a different environment that the other such as Test and Production and they need to be run side by side.

  6. DataDirectory is the "entry" point to data sources settings. The DataDirectory member gives the location where a data file such as a database or a data file is stored in the local application store (temp cache directory). Use the DataDirectory location to get to the “entry point” required data such as connection strings or paths etc… So for example, if the client app needs to access central data stored in a database, then the natural place to add the connection string is from the application GUI. This is so because usually, the connection string passwords need to be encrypted, so functionality is required and mind as well add this layer of functionality to the existing GUI (most simple cases). Another example (although not recommended except for very simple apps) is if your application needs to update a central data file in some standard location, then by the same token, have this functionality to add the path to this central data file in the application GUI where the user is prompted and can edit it any time from a friendly interface. The app will write this path to the local data file in the app storate data directory and it will be preserved across different versions.

I hope you find the above brief explanations helpful. If you have any comments, corrections, questions or need further explanation, please feel free to leave a comment and I would love to try and help out.