When writing my own auto updater, is there a general framework that I should be following?
A while ago I was reading up on how one should create a 'boot strapper' that will load first before the main application (since a running appilation can't be updated due to file locks etc.)
So any tips/best practices for this?
Ok, first of all, if one of the installer/updater products out on the market fits your need, you should probably use those. That being said, I've had the pleasure of building a system like this myself not long ago. Yes, our installer/updater included two parts on the client side so that:
~ Part A would connect to the servers where the latest version is stored and published; if a newer version of Part B was available, it would download it and kick it off
~ Part B would focus on installing/updating the actual application (and could download and install updates to Part A).
Aside from that, I'd recommend always considering the following 4 operations in the installer/updater:
Install and Uninstall
Update and Rollback (i.e. undo the last update)
The Rollback one is critical when your users have a system that automatically updates overnight.. if an update every messes up, they can rollback and continue working while you fix the issue.
Finally, the installer/updater should try and be agnostic about the application it installs/updates, so that, when that application changes, the installer/updater system is impacted the least possible amount.
This zip contains the source code for a word search generator tool that includes AppUpdater boilerplate code.
http://cid-842434ebe9688900.skydrive.live.com/self.aspx/Games/WordSearchGenerator-src-v1.3.zip
Look for the 3 source modules that have "AppUpdater" in the name.
It is very simplistic and works only for single-assembly applications. No MSI file. Just an EXE. The philospohy is that update checks happen automatically, but updates are installed only after user confirmation.
The way the updater works:
It loads an XML document from a URL that contains the "latest version" information, as well as a second URL where the actual new version is located. The updater logic verifies the signature on the XML doc, but you may not care about that. The updater then compares the current version against the latest version, and can tell the application if an update is available. The updater also handles the replace-in-place problem.
In this model, there are three "lifecycle stages" of an app during an update. In the normal course, the app checks for updates, and then runs as normal. At some point the user may confirm that they want to install the available update, and the Updater downloads the app to a temporary location, then starts a process using that newly downloaded exe. The updater logic then exits the first process. The second process, based on the command-line-arguments given to it by the first process, realizes that it is a newly downloaded copy and needs to replicate itself. It copies itself to the original location (specified on the command line), starts that exe, and exits. The third process starts as normal, sees that there has been an update, and deletes the temp exe copy. It then runs as normal, including checking for updates. It will find that there are no updates, and will then just run as normal. That covers the operation of the update-in-place logic.
This is all handled by these lines in the constructor of the Windows Form or WPF Window:
The check-for-update problem is also handled by a few lines of code in the constructor, that create and run a background worker thread:
The CheckLatest is this:
The completed event is this:
It works from WinForms or WPF apps. I guess it would work from console apps as well, but I have never tried it.
Creating the (possibbly signed) manifest file is a separate task, not covered here.
Thinking about it, this might better be packaged as a base class AutoUpdatingForm (for WinForms) or AutoUpdatingWindow (for WPF). But I never took that step.
I coded an updater for an app I worked on in C++, but the general structure would be the same.
This worked pretty well for us, and as it always downloaded a new "updater" as the first thing it did, we could handle some funky new things that might not work otherwise.
If you're using .Net why not just use ClickOnce? It will do everything you're talking about out of the box and requires almost zero setup.
There's an article on this at CodeProject: "Application Auto Update in VB.NET" at https://secure.codeproject.com/KB/vb/autoupdate.aspx and https://secure.codeproject.com/KB/vb/Auto_Update_Revisited.aspx
And another good one here: Custom Application Auto Update": https://secure.codeproject.com/KB/vb/CustomAppAutoUpdate.aspx
You'll probably have to write your own. As FOR mentioned, the basic idea is to put the latest version of your program (I'm assuming an EXE) on the server, and then have your application check with the server when it starts, and download the EXE from the server if it's a newer version.
I've usually implemented this as a web service that the application calls at startup. A couple of warnings about this approach:
The web service method needs to get the version number of the EXE on the server and compare it to the version number of the caller. If you use the Assembly class to read the version number of the server EXE, this will lock the file for as long as the web service instance is running (at least 20 minutes). As a result, you may sometimes have trouble replacing the EXE on the server with a newer version. Use the AssemblyName class instead - this allows you to read the assembly info without loading the assembly (and locking it).
The caller application can't replace its own file with the new version - you can't delete or update a running application file. What it can do, however, is to rename its own file while running. So the trick on an auto-update is for the application to rename itself (e.g. "MyApplication.exe" to "MyApplication_OLD.exe"), download the new version into the application folder (named "MyApplication.exe"), notify the user that an update has occured which requires a restart of the application, and then end. When the user restarts the application, it will be the newer version that starts - this version checks for and deletes the old version.
Doing an auto-update that automatically restarts the application after an update like this is very tricky (it involves kicking off another process and then ending its own process before the auto-restart process kicks in). I've never had a user complain about having to restart the app.