Automatic Updater - when simple things are not obvious

Vitalii Symon, 30 September 2010

Every program which is not a CD Ejector v 1.0 needs to be updated from time to time. There are hundreds of things that can cause a need to change, add or remove something. One of the primary reasons is bugs which make a user’s experience horrible and need to be removed urgently.

This topic seems to be very simple and senseless to write about for a blog post and most likely you think that a simple batch file or WebClient.Download() would be plenty enough - Actually no. If you make a mistake in the update program you’ll need to do manual update for all 10-20 pc stations or even better - explain brilliant rescue plan to each user separately. Hacking NASA servers and updating TV satellite software to get a free boxing channel would be easier.

So here are few important tips about making updates.

1. The most important thing is to make updater application updatable. If you can change way the application updates – you can control and modify logic later. Why? Because nothing is perfect and nothing is eternal.

Example. You have a program which uses document templates and a customer wants templates to be editable easily from a user’s machine. What should we do if the updater is constant?

Automatic Updater - when simple things are not obvious

Fig. 1. Template server has to push templates onto update server which needs extra actions

Amend files -> grab update archive from server -> put new files inside -> upload zip - > ready for update

The bold part is totally redundant and will need the user to click more buttons, but he (or she) will probably forget to do that and will write you an email ‘hey, you, my program doesn’t work. Fix it!!!’ and put the boss into cc. Of course you’ll answer something like ‘sorry for the problem, but most likely you forgot to click ….” But, more often than not you will look like the guilty suspect in the dilemma Want to avoid this? Do smart updater - this will:

Automatic Updater - when simple things are not obvious

Fig. 2. Client communicates directly to template storage and there’s no need to do extra work like unzip download-update-add templates-zip-upload

The updater will pick those files separately and no extra actions are required.

Solution: download new updater under other name (e.g. updater_new.exe) and add code to rename it in the main program.

2. Crashing. Even the best code crashes sometimes. If you do not want to write code with bugs – don’t write code at all. Most likely there will be hundreds of ways to get an exception – UAC, internet connectivity, unclosed program (and problems accessing binaries), antivirus, and more.

Solution: many try {} catch {}, logging, simple and reasonable logic for handling crashes.
Thus you have to create strong rules for what to do if program has crashed –it makes sense to say to the user that the update failed and launch main app automatically. And then the main app will detect a new version and launch the updater again and …

3. We get infinite loop. This happens when the main program runs the updater - the updater fails and runs main app and so on. There are few ways to avoid this trouble but IMHO the best one is to set a rule like not more than 1 update in an hour. Or two hours.
Just create a timestamp when last attempt happen and check next time. That will reduce number of unhappy customers which will have to catch appropriate moment to close update window.

4. Configuration. Most likely your program has settings. Many settings. And sometimes you add new ones and one day your updater will have to replace the user’s configuration file. Make sure your program can handle empty settings file and prompt user with configuration dialog.

5. UAC. Just keep this in mind. Always.

This post is not rocket science for products with millions of users but just a list of tips which save me extra headache each time I find a new problem. These simple and obvious tips will save your time, reduce number of RDP sessions and angry letters from unhappy customers. Happy coding.