Problem description: We a desktop application including other components like windows service, Local SQL express database etc. The first release of our application will be part of our gold build and we will be having full control over target environment. Once the build is released to our remote customers we will lose our control over that environment. We need to provide on-going application update mechanism for each client at the same time; any unauthorized users should not be allowed to access these updates. Each client might have different application versions installed and maintained. The system should allow us to control who will receive the application update, let’s assume we will charge our customer for 6 months of updates…
Solution Summary:
- Use ClickOnce as base deployment technology.
- Provide client side ClickOnce proxy (clickonce wrapper) component which can be integrated in any client app.
- Build Asp.net server side HttpHandler with client authentication and security.
- Build some trust mechanism between client and server side component.
- Prepare you initial build and use CD as deployment method (full trusted) and configure some parameters. Some components which might not need any updates like Windows host service; SQL instance etc could be deployed as msi installation.
- The server side component should record the client ip-address and at some later stage, plot these locations on Bing map or google map. – (out of scope at this stage)
Theory:
How ClickOnce Deployment Work’s: The core ClickOnce deployment architecture is based on two XML manifest files: an application manifest and a deployment manifest.
The application manifest describes the application itself, including the assemblies, the dependencies and files that make up the application, the required permissions, and the location where updates will be available. The application developer authors the application manifest by using the Publish Wizard in Visual Studio or the manifest generation tool (Mage.exe or MageUI.exe) in the .NET Framework SDK.
The deployment manifest describes how the application is deployed, including the location of the application manifest, and the version of the application that clients should run. An administrator authors the deployment manifest using the manifest generation tool (Mage.exe) in the .NET Framework SDK or Visual studio publishing wizard.
How ClickOnce Performs Application Updates: ClickOnce uses the file version information specified in an application’s deployment manifest to decide whether to update the application’s files. After an update begins, ClickOnce uses a technique called file patching to avoid redundant downloading of application files. File patching :When updating an application, ClickOnce does not download all of the files for the new version of the application unless the files have changed. Instead, it compares the hash signatures of the files specified in the application manifest for the current application against the signatures in the manifest for the new version. If a file’s signatures are different, ClickOnce downloads the new version. If the signatures match, the file has not changed from one version to the next. In this case, ClickOnce copies the existing file and uses it in the new version of the application. This approach prevents ClickOnce from having to download the entire application again, even if only one or two files have changed.
Choosing a ClickOnce Deployment Strategy: There are three different strategies for deploying a ClickOnce application; the strategy that you choose depends primarily on the type of application that you are deploying. We will use “Install from a CD” in this scenario.
When you use this strategy, your application is deployed to removable media such as a CD-ROM or DVD. As with the previous option, when the user chooses to install the application, it is installed and started, and items are added to the Start menu and Add or Remove Programs in Control Panel.
This strategy works best for applications that will be deployed to users without persistent network connectivity or with low-bandwidth connections. Because the application is installed from removable media, no network connection is necessary for installation; however, network connectivity is still required for application updates.
To enable this deployment strategy in Visual Studio, click From a CD-ROM or DVD-ROM on the How Installed page of the Publish Wizard.
To enable this deployment strategy manually, change the deploymentProvider tag in the deployment manifest so that the value is blank. In Visual Studio, this property is exposed as Installation URL on the Publish page of the Project Designer. In Mage.exe, it is Start Location.
Choosing a ClickOnce Update Strategy: ClickOnce can provide automatic application updates. A ClickOnce application periodically reads its deployment manifest file to see whether updates to the application are available. If available, the new version of the application is downloaded and run. For efficiency, only those files that have changed are downloaded.
When designing a ClickOnce application, you have to determine which strategy the application will use to check for available updates. There are three basic strategies that you can use: checking for updates on application startup, checking for updates after application startup (running in a background thread), or providing a user interface for updates. When using this strategy (user interface for updates), the application developer provides a user interface that enables the user to choose when or how often the application will check for updates. For example, you might provide a “Check for Updates Now” command, or an “Update Settings” dialog box that has choices for different update intervals. The ClickOnce deployment APIs provide a framework for programming your own update user interface. For more information, see the System.Deployment.Application namespace.
If your application uses deployment APIs to control its own update logic, you should block update checking. To block update checking, clear the application should check for updates check box in the Application Updates Dialog Box. You can also block update checking by removing the <Subscription> tag from the deployment manifest.
This strategy works best when you need different update strategies for different users.
Publish Directory Structure
The folder and file structure created by Visual Studio 2005 includes a root folder for the application, a default deployment manifest, a version specific deployment manifest, and a subfolder for each version of the application. The subfolder contains the application files suffixed with a file extension of .deploy and the application manifest for that version. The .deploy extension is added to all of the application files by default when publishing from Visual Studio to simplify the configuration required on the deployment server. Doing so ensures that the only file extensions you need to set up mime-type mappings for are the .application, .manifest, and .deploy files. The runtime on the client will remove the .deploy file extension after download to restore the original file name.
Additionally, a Setup.msi file for the configured pre-requisites is placed in the root-publishing folder, along with a publish.htm file that can be used to test the deployment. The default deployment manifest (the one without a version number embedded in its name) in the root folder is updated each time you publish a new version so that it always refers to the application manifest in the most recently published version. Figure A-1 depicts this folder structure for an application published to the local machine instance of IIS.
The structure used by Visual Studio is arbitrary and does not have to be followed explicitly if you manually publish your applications. The deployment manifest contains a path to the application manifest, and the application manifest contains relative paths to the application files. As a result, they can be placed in whatever folder structure you choose if you create or edit your manifests with Mage.
ClickOnce Reference: http://msdn.microsoft.com/en-us/library/6ae39a7c(v=vs.90)
Administering ClickOnce Deployments: http://msdn.microsoft.com/en-us/library/aa480721.aspx
ClickOnce HttpHandler: http://www.codeproject.com/Articles/176120/ClickOnce-Licensing-HTTPHandler
Check for updates : http://msdn.microsoft.com/en-us/library/ms404263(v=vs.90)
Implementation:
Creating Scenario: We have to split our application into two components, one which requires update and another one which doesn’t change or requires update like bootstrap program, SQL server installation etc. Pack one component using ClickOnce publishing tech. mentioned above and pack another one using msi. Now pack these two into single MSI. The setup is ready for rollout on CD.
We definitely need some short of unique ID (say GUID) to identify each client, lets assume on our service side we have this information available in xml file. These Id’s will be provided as part of first installation bundle and each update request will have this id in query string. At server end,ASP.net httpHandler will log the source ip address and validate the client id from it local xml file and respond as per our business rule.
So the next important thing we need is the server side component of ClickOnce, i.e Asp.Net HttpHandler. The problem with the custom approaches (asp.net HttpHandler) is tied to the fact that when a ClickOnce application is installed or updated, a series of separate file requests come in to the deployment server from the client machine. There is no way for the deployment server to identify who those calls are coming from and that they are all part of a single logical installation or update “session” from the perspective of the user and the client application. The only way to solve this problem is to introduce something onto the client that can make an association between the individual requests and introduce information into the calls leaving the client to identify the user to the deployment server.
This kind of client side interception of requests is exactly what an HTTP proxy was designed for, even though they are usually used for other purposes related to network infrastructure security. If a proxy can be introduced on the client that intercepted requests destined for one or a set of ClickOnce deployment servers, and added user credential information to those requests before they left the client machine, then those credentials can be used on the server not only for authenticating the deployment manifest requests, but for all file requests on the server. The proxy adds a custom cookie to the HTTP requests that contained the user credentials. You then need some code on the server side, such as another HTTP module, that checks for the presence of those cookies and only allows authenticated access to the server
Using a Custom to Establish an Application Session: As described in an earlier section, if you can introduce a custom proxy on the client side, you can ensure that a user token is included with every request for ClickOnce manifests or application files that leave the client machine for a particular site or set of sites. As a result, you can use the user token to make authorization decisions on the server side to determine whether to return the requested file or not. This can again be done using a custom authorization HTTP module that extracted the user token (typically in cookie form) and used it to decide whether to satisfy the request.
The downsides to this approach are the complexity in setting up the custom proxy as discussed earlier, as well as coming up with a way to store and associate user tokens on the client side that is secure. To protect the token in transit, SSL would work fine, and token lookup on the server side could be done using the ASP.NET Membership API or some other custom database lookup.
Content Type Mappings: When publishing over HTTP, the content type (also known as MIME type) for the .application file should be “application/x-ms-application.” If you have .NET Framework 2.0 installed on the server, this will be set for you automatically. If this is not installed, then you need to create a MIME type association for the ClickOnce application vroot (or entire server).
If you deploy using an IIS server, run inetmgr.exe and add a new content type of “application/x-ms-application” for the .application extension.
Coming Soon with ref implementation