views:

1896

answers:

15

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?

+2  A: 

Unfortunately there is no Sparkle or update-engine for .NET. There is the Updater Application Block for .NET released by Microsoft, that's your best bet if you don't want to completely roll your own solution (there's still a bunch of code you'll need to write though).

Stewart Johnson
I was going to mention the Updater App Block, but it doesn't seem to be in the current revs of EntLib. (We're still using 3.1 here, but I was looking at the 4.1 docs and didn't see it ... did it get removed at some point?)
John Rudy
John, it was replaced with ClickOnce (which is not as flexible)
ASDFdotASPX
A: 

Ten years ago I wrote an auto updater (not in .NET), but the gist of it was that the application had a version id that was checked on startup. In this case the app queried a database table that had the current version and if the running version was less than the current version, the user was prompted to download the latest version. The same thing could be accomplished by checking a URL.

Paul Croarkin
This is a simple way to do it and works just fine. Suppose you define an app version xml schema, and a URL where you can get a new app version. Using XML-serialization it's very simple. The things that can make it complicated are when you want to use a signature on the version document, to provide integrity checks, and how to do the replace-in-place if there is actually an updated version.
Cheeso
+1  A: 

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.

Echostorm
+6  A: 

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 partions 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 consideriung 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.

FOR
+1  A: 

ClickOnce didn't work well for us. We install the database on our customer's server. The database on their end needs to be updated before we do an update. We have a lot more than just 2 or 3 customers, so doing ClickOnce for our application is not really the best idea, unless I am missing something important about ClickOnce.

What I did, was add a field to the database for version number. On our ftp site, I have a versions folder that has a folder for each version number of our application. Inside that particular version's folder, we put a zip file with the setup.exe and the msi file that the setup.exe will launch. All the pre-reqs are downloaded from the vendors site to ensure that our FTP site isn't getting hit with huge downloads (.Net 3.5 when we moved to it). When our application launches, it checks the field in the database for the version number, and if it's different than the current versions assembly version, it will connect to the ftp site, download the zip file from that new version's folder, unzip it, and execute the setup. This will install newer versions of .Net or any other requirement we may have added, then launch the MSI to install our application and all the user has to do is click next a few times.

TheCodeMonk
+2  A: 
crashmstr
+2  A: 

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

amdfan
your links are going to theege.com for me? wierd!
ASDFdotASPX
+8  A: 

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:

  1. 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).

  2. 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.

MusiGenesis
+4  A: 

here is a decent one that i tested a few months ago and will be using shortly

http://www.ddaysoftware.com/Pages/Projects/DDay.Update/

quimbo
+1  A: 

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.

Cheeso
A: 

Let me start by saying we offer a complete updating solution which includes:

wyUpdate handles all of the Vista/Windows 7 UAC problems and all the file permission problems that inevitably pop up when you're trying to update complex software.

That being said, if you want to build your own updater here are some tips:

Building your updater

A good place to start is the wyUpdate C# source code I mentioned above. You can cannibalize it and use it for your own purposes. Some of the algorithms it contains:

  • Full Windows Vista / Windows 7 UAC support
  • Ability for limited users to check and then update if they have credentials
  • Support for wonky corporate inernet. (If you've ever worked with a corporation this is a real problem).
  • Quick extracting, patching, and installing of files.
  • Registry support.
  • Roll back files & registry on error or cancellation by the user
  • Self-update

We have the file specifications here.

Automatic updating

Since being automatic is a requirement let me tell you how we do it with our AutomaticUpdater control.

We use named pipes to communicate between the standalone updater (wyUpdate) and the Automatic Updater control sitting on your program's form. wyUpdate reports progress to the Automatic Updater, and the Automatic Updater can tell wyUpdate to cancel progress, to start downloading, start extracting, etc.

This keeps the updater separate from your application.

In fact, the exact named pipes C# code we use is included in an article I wrote a little while back: Multi-process C# app like Google Chrome.

Wyatt O'Day
+2  A: 

Wrote our own automatic update software. So here's my tip... Don't do it!! Of-course this all depends on your specific scenario, but here are the problems that my company encountered:

  • Difficult to support on an ongoing basis, especially if you target Win2k through to Windows 7.
  • Challenges with permissions. WinVista/7 UAC can be a real pain.
  • Flexibility is a requirement, but you won't be able to foresee all issues. For example, starting/stopping services, launching files etc. are all tasks that you MAY want to do for your automatic updates, but which you won't necessarily foresee.

The problem with our software is that we needed a lot of flexibility and support on all Windows platforms. The solution we wrote worked fine, but didn't scale and started to fail when Windows versions changed or weren't quite like those in our lab. We ultimately bought software and I recommend you do the same. If you are interested, we bought a product called AutoUpdate+ (link text).

Testing123
+2  A: 

Hi,

you can take a look at BitsUpdater. It is simple and extendable library for automatic update process using BITS (technology used by Windows Update).

There is a sample for processes (special project called ApplicationLauncher) and you can extend library with your own solution for updating any other services (database, ...).

jakubgarfield
+3  A: 

Here's an open-source solution I wrote to address specific needs we had for WinForms and WPF apps. The general idea is to have the greatest flexibility, at the lowest overhead possible.

So, integration is super-easy, and the library does pretty much everything for you, including synchronizing operations. It is also highly flexible, and lets you determine what tasks to execute and on what conditions - you make the rules (or use some that are there already). Last by not least is the support for any updates source (web, BitTorrent, etc) and any feed format - whatever is not implemented you can just write for yourself.

Cold updates (requiring an application restart) is also supported, and done automatically unless "hot-swap" is specified for the task.

This boild down to one DLL, less than 70kb in size.

More details at http://www.code972.com/blog/2010/08/nappupdate-application-auto-update-framework-for-dotnet/

Code is at http://github.com/synhershko/NAppUpdate (Licensed under the Apache 2.0 license)

I plan on extending it more when I'll get some more time, but honestly you should be able to quickly enhance it yourself for whatever it currently doesn't support.

synhershko
-1: stop cut/paste spamming the .net/update tags please.
SnOrfus
I wasn't aware of this definition for spamming: "answering people's questions". Yes, I'm doing some PR, but this isn't a commercial product (like other responses to those threads) and it does have value to the asker (or future reference).
synhershko
ditto .........
qstarin
Thanks for the answer. I will take a look at it.
gyurisc
A: 

One of the solution I have yet to try is to have an installer that can run in silent mode.

The application call the server and if it needs to update, it downloads the last installer then runs it with a silent or an update flag.

It has a lot of benefits :

  • flexibility : you can do anything you would do for a normal install
  • no extra package : the installer and the update are the same thing
  • if you uninstall then reinstall, you can handle rollbacks
  • the update is a separate process, so it can launch the app when the install is complete
  • you have tools to handle vista UAC
Emmanuel Caradec