Reprinted from Http://windowsforms.net/articles/appupdater.aspx
. NET Client applications:. NET Application Updater Component
I recently received a mail from the Microsoft IT team notifying me this they had detected several applications on my Deskt OP computer that did not have the latest patches installed and instructed me to install the latest. Ill be the "I admit" I dont update the applications I run as much as I should; Either on my home machine or in my work machines. It usually takes a problem like a broken feature in a application or a email (or sometimes several) from the IT Departme NT, to get me to install updates. Unfortunately Im more of the "rule than" exception when it comes to users updating their.
This requirement of needing a user or admin to manually install an update are why rolling out client updates has Traditiona Lly been such a huge problem and expense. One solution is to move the responsibility of updating the application from the user to the application itself. Instead of the user obtaining and installing a software update, the client application itself is responsible for Downloadi Ng and installing updates from a-known server. The only user interaction necessary are whether or not they want to install the new updates now or later. You can-this type is approach to updating applications in action today, with the products like Windows XP and Microsoft Mon ey.
In this article we'll talk about a approach to building. NET client applications then are able to automatically update themselves.
The . NET Application Updater Component
Included with this whitepaper are a component for enabling. NET client applications to automatically update themselves. The component was written using the. NET Framework and enables for your to make your application auto-updatable simply by Dropp ing the component into your existing. NET applications and setting a few properties (ex. Where to get updates from). Download the. NET Application Updater Component.
This component isn't a Microsoft product. It is intended as a for you started and as such the ' source is also included with this whitepaper. However, it is worth mentioning the This component has gotten a fair amount of the real world. It has been used internally in Microsoft to enable auto-updatability in the. NET terrarium Game (http://windowsforms.net/t Errarium). Terrarium has been installed and used by over 10,000 individuals since it is the it was a beta product in unveiled, 2001.
This component is the basis for the discussion of what it takes to make a application auto-updatable. This paper would focus on how the. NET Application Updater Component works and how to you can use it in your own application.
Checking for Updates
The thing a application needs to being able to does in order to update itself are figure out when a new update is Availab Le. In order to does this a application needs to know three things 1) where to check for updates, 2) when to check for updates and 3) How to check for updates. The application update component uses HTTP for all network communication. This is allows it to update applications over the intranet or extranet. Thus the Where to check for updates are simply a URL to a, known Web server.
To address the "when" Check for updates, the. NET Application Updater component creates a thread on component creation The ICH is responsible for checking for updates. This thread would sleep for most of the time, but'll wake up in the configured interval to perform an update check. How to often the application checks for new updates are dependent on the individual application, but common values range from One hour to one day between update checks. This polling based approach isn't appropriate for all applications, for example Microsoft money only checks for updates W Hen the user tells them to. In this case, the update poller thread can is disabled and update checks performed On-demand by calling the Checkforupdate () method on the Updater component.
There are several ways to go about the "how to" Check for updates:
method #1: Direct File Check The simplest way to check for updates are to use HTTP to compare the last modified Date/time stamp of the application file s on the server and that is on the client. If the server has newer files, the client knows its time to update itself. This is the same way a Web browser knows if it needs to re-download an HTML page or image or whether it can just re-use th e one previously downloaded. This is certainly the simplest to administrate. When a new version of the "app is available", the administrator simply copies the newer version over the older version on th e Web server. The problem with the "is" is "not atomic and thus there are potential windows of failure." For example, if an administrator updates the version of the app on the WEB server while a client is in the middle of Loading the previous update, that's client may is left with some files from the previous update and some files from new UPDA Te. For this reason, the using a direct file check is not recommended to any NON-TRivial applications.
Method #2: Manifest Check To solve the atomicity problem and direct file checks a level of indirection is needed. To create a level of indirection a manifest file on the server is used. A valid server manifest file with the. NET Application Updater Component as this:
<VersionConfig>
<AvailableVersion>1.0.0.0</AvailableVersion>
<ApplicationUrl>http://localhost/demos/selfupdate/V1/</ApplicationUrl>
</VersionConfig>
AVAILABLEVERSION Specifies the assembly version number of the latest available version. The ApplicationUrl property specifies the URL where that version of the application resides. When the "administrator" wants to update the client applications, they would copy the new version of the "app" the "Web s Erver and modify the server manifest file appropriately. The client itself would then detect that the server manifest file has and changed the download file. The client then compares the assembly version number specified in the manifest with the assembly version number of the app lications. exe file. If the server manifest file availableversion is newer, the application knows it time to perform an update. This approach has none of the atomicity problems of the previous approach and are the recommended to check for way For most applications.
method #3: XML Web Service Check XML WEB Services provide a way to perform more advanced update checks. For example, suppose your wanted to roll out an update to a set of early adopters before your rolled it out to the rest of Y Our users. If the client application calls a XML Web service to check if a update is available, that XML Web service could then loo K up so user in a database and determine if the user was an early adopter or not. If They are, the XML Web service could return a value indicating this update is available. If not, the Web service could return a value indicating this a new update is not available. Because the Web service used to check for updates could take many forms depending on what custom functionality is desired The. NET Application Updater Component does not provide direct XML WEB service support. To use an XML Web service to check for updates, the the XML Web service and then hook the Oncheckforupdate event. This allows the Poller threads update Check to is replaced with your OWn Custom Check. The Oncheckforupdate event has a return value to indicate whether an update is detected or not.
Downloading Updates
Once the application determines a new update is available, the update needs to be downloaded. By default, when the. NET Application Updater Component detects this a new update is available it'll automatically kick Off another thread and start a asynchronous background download of the update. The download is done using Http-dav. The DAV is a extension to HTTP that provides functionality such as directory and file enumeration. A complete and deep download is do starting with the specified URL. The URL used to download depends in the type of update check being done. For example, if a server manifest are used, the URL to download the update from be specified by the ApplicationUrl property In the server manifest.
The download of the update obviously needs to be robust. Leaving the client application in the kind of the download and update is unacceptable. Any number of problems could occur during the Download:the WEB server where the update resides could to down, the client Machine could crash, or for this matter the user could simply down the shut application. Since The application is what is doing the download, if it shut down, the download would stop. An alternative design would have been to use a separate system service to do the download and update of the application. With a system service, the download of the "update could continue even when the application itself are not running. In fact, Windows XP has a built-in download service called BITS for just this purpose. BITS is what the Windows XP uses to download updates to Windows itself. For more information on BITS, http://msdn.microsoft.com/library/en-us/dnwxp/html/WinXP_BITS.asp. A service wasn't used in the. NET APplication Updater Component So this it would work on the Windows 9x operating systems does not which system service S.
The. NET Application Updater component achieves robustness by breaking the download and update process into separate stage S. As each stage are complete, it is recorded in a updater manifest file which in the resides directory on the Client. If the download or update process is interrupted in any stage, it would simply resume from the "point of" the last completed Phase the next time, the app is started. Each stage are re-run able so this if a failure occurs in the middle of a stage, re-running the stage from start would succe Ed. If A error occurs, such as the loss of connectivity with the WEB server during a download, the. NET Application Updater C Omponent'll simply try again later. If enough failures are reported (ex. The WEB server never came back online), the download and update is aborted and an error reported.
Performing Updates
Once The new update has been downloaded, the last of the step was to apply the update. This is far the most challenging. The fundamental problem is that the application are trying to update it own files while running. Thus the files are locked. The only way to unlock the files are to stop the application, but if you stop the application, how can it update its files? Its a Catch 22. We went through several designs before we came up with our final approach. Before I describe the final design, lets look at our a approach and describe its shortcomings.
Our approach is to simply kick off a separate process to perform the update. This separate process would the application process of the Shut, perform the update (since the files were now unlocked ), restart the application process and then shut itself down when complete. However, there were three fundamental problems with this design:
It simply did not work in some scenarios. For example, Windows runs screens savers in what is called a Job object. The defining characteristic of a job is ' that ' when the root process of a job are shut down, all processes it created are ALS o Shut down. This is makes sense when you are about it. When a screens saver goes away, you want to make sure it all goes away. However, in the "Application update case," The updater process shut down the original application process, the updater Process itself would also is shut down and thus no update performed.
We wanted to is able to automatically update all of the code that performed the update. In the course of use, we would find bugs in the. NET Application Updater Component, (ex. A Timing window that would effect 1% of clients), and we wanted the ability to automatically out roll of not fixes th e application, but the. NET Application Updater component as. With this model, we could the "not update" process that performed the update.
Forcing the user to shut down the application and the middle of the ' use ' was undesirable.
The final approach used to perform the application update is inspired by the side-by-side model of the. NET Assembly Ework. Instead of trying to update the application itself, create a new upto-date version of the application next to the existing Version. The new version can be created by merging to the existing application directory with the downloaded update. When the new version is complete, the user would automatically use that version of the next time they launch the application. The original copy of the application can then be removed. This tricky the figuring out which version to launch in any given time. To did that, a program named Appstart is introduced. Appstart is the entry point into your application. With this model, your application directory would look something as this:
Program Files
MyApp
Appstart.exe
Appstart.config
V1 Folder
MyApp.exe
V1.1 Folder
MyApp.exe
To run your application, you always run Appstart.exe. If you want a shortcut on the desktop, the shortcut should point at Appstart, not at the application directly ou can rename AppStart.exe to be whatever for you want, ex. YourApp.exe). Appstart.exe is a very the reads the Appstart.config file and launches the specified. A valid Appstart.config file looks like the following:
<Config>
<appfoldername>v1 folder</appfoldername>
<AppExeName>MyApp.exe</AppExeName>
<AppLaunchMode>appdomain</AppLaunchMode>
</Config>
The appfoldername specifies the subfolder that contains the "current version of the" app to run. The appexename contains the name of the EXE within that folder to launch. When a application update is complete, the final ' step is ' to ' change ' appfoldername value to point at the new version of The application. Thus the next time the user runs the application, they'll run the new updated version of the application. The Applaunchmode specifies how to launch the application. There are two ways to launch the application. This is the approach with AppDomains. AppDomains are a feature of the. NET Framework Common Language runtime and the logical unit of isolation and Administratio N of objects. The common language runtime allows multiple application per process. Thus Appstart.exe can launch your application in a separate AppDomain but within the same process. Thus, despite the fact that two different exes are running (in this case Appstart.exe and MyApp.exe), only one PROcess is used. For most applications AppDomains would work, however there are a few minor differences with running in a separate APPD Omain vs. a separate process. For this case, the Applaunchmode can is set to process which would cause the application to launch in a separate process.
Once Appstart has started the application, it'll go to sleep and wait for the application to terminate. Once the application terminates, Appstart'll also shut down. However, if the application shuts down with a-i-known return code, the Appstart process would re-read the APPSTART.CONFI g File and re-launch the application. This is useful if the user wants to begin using the "new" version of the application immediately after it is available.
Using the. NET Application Updater Component
Now this weve discussed how the. NET Application Updater works, and lets put it in action. A very simple Windows Forms application. Then we enable it to auto-update itself using the. NET Application Updater component. Finally, deploy the application and the Auto-update feature in action.
Included with this paper be a zip file named Dotnetupdater.zip that contains the. NET Application Updater component. The zip file also contains a Sample directory which contains a number of files and folders we are using in this walkth Rough.
Step 1:build The application to update
In here step we'll build the application to Auto-update. If you are want, you can substitute the your own application here. You can also use the pre-built sample application included in the Samples/sampleapp/sampleapp directory of the zip file. However for the purpose of proving, there isnt anything special about sampleapp, and walk its through.
1. Use Visual Studio. NET to create a new Windows application project, name it SampleApp.
2. Give the form an interesting background color of your choice. We are using background color to differentiate between versions later.
3. Now lets add a tiny bit of functionality to this application in the form of a button that opens a form residing I n a separate assembly. A button to your form. The zip file contains an assembly and simple Windows Form in it. ADD a reference to the Samples/sampleapp/simpleform assembly in the zip. Then add two lines of code to your button event handler:
Simpleform.form1 F = new Simpleform.form1 ();
F.show ();
4. Switch your build flag to builds release instead of Debug. This is allow us to avoid PDB file locking problems later when we build a new version of the application while the Origi NAL copy is still running.
The
5. build and test your application. It should look Si