One of the features we wanted in iMo windows version was it should periodically check for updates and prompt user to upgrade if updates are available. Update should be just 1 click process. Since iMo integrates deeply into the operating system, using ClickOnce was not an option. One additional constraint was we are using Visual Studio Setup to deploy our application so update mechanism should also be through it (to avoid inconsistencies like in “Add-Remove programs” it shows version 1.0.9 where as you really have 1.1.3).
As always, I tried to find an existing opensource solution but found none which satisfied complete requirements so I went ahead and wrote a custom solution. Most of it is copy-paste from code project, msdn, google etc. Links to referances at the bottom.
I will outline my approach here. Looking forward to heard your approaches and any loopholes mine might have. So here we go :).
Step 1 : Download the text file from server and compare with current version:
I used WebRequest asynchonously to download the file. Don’t use the main thread as it might take few seconds and user might feel application hung. Now you don’t want to be doing this each time your application starts (once a day is good enough number). To save the lastUpdateCheckTime, I used User Settings. Its much better and cleaner than using registry or maintaining your own text file. You can get more info on User Settings here.
Step 2 : Update available, Now What:
Prompt the user if he wants to update now or later. If he clicks once, I don’t prompt him for next 4 days but start showing a small button in the corner for “Update Now”. If he says, yeah I want to update now, download the latest Msi setup from webserver in “Temp” folder. To download the file, I used WebClient.DownloadFileAsync. Show a progress bar on your application to show the download progress. Bonus points for allowing user to use the application while the update is being downloaded :).
Step 3 : Verify Downloaded File:
Haven’t finalized this, but will most probably be using the signature to verify.
Step 4 : Prepare for the update:
Now, you can’t replace an application while its running. Some people rename their main application and update but I feel its a very ugly hack. I included a small “iMoUpdate.exe” which was copied to “Temp” folder by main application and started and then the main application shut itself down. The job of iMoUpdate.exe was to just run the setup we downloaded in Step 2.
Step 5 : Run update:
“msiexec” is a small utility included with all new versions of windows (XP+). Run it using System.Diagnostics.Process and give arguments “/qb” and path to your downloaded Msi setup which runs it in quite mode ie it will just show a progress bar and not prompt the user at all. Bonus points for restarting the main application again after update is complete:).
Thats it! Simple and easy. Less than 50 lines of code.
- One important thing which I added later was a Mutex in “Step 5″ which makes sure that the main application has exited before running the update setup using “msiexec”
- Based on feedback, I am attaching the file containing code snippets for each of the steps. You can download it here. Its not commented or Step by Step but should help in copy pasting/googling :)