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:
_Updater = new AppUpdater.SimpleAppUpdater(_MyManifestUrl);
_Updater.Startup(App.CommandLineArgs);
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:
_Worker = new System.ComponentModel.BackgroundWorker();
_Worker.DoWork += CheckLatest;
_Worker.RunWorkerCompleted += CheckCompleted;
_Worker.RunWorkerAsync();
The CheckLatest is this:
void CheckLatest(object sender, System.ComponentModel.DoWorkEventArgs e)
{
lock (_Updater)
{
if (_Updater.UpdateIsAvailable) // Checks for update
{
// can update a textbox (etc) here. Be careful of InvokeRequired.
}
}
}
The completed event is this:
void CheckCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
{
if (!e.Cancelled && e.Error == null)
{
lock (_Updater)
{
// only display the about box if there is an update available.
if (_Updater.HaveCheckedForUpdate && _Updater.UpdateIsAvailable)
{
// do whatever you want here. Eg, pop a dialog saying
// "an update is available"
About about = new About();
about.Message= "An update is available";
about.ShowDialog();
}
}
}
}
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.