SimpleUpdater as a ClickOnce Alternative
updated 6 years ago
I recently evaluated ClickOnce as a technology for keeping an application updated. It worked as expected and was quick to implement because of the built-in support within Visual Studio. However, the following issues kept me from using it:
- ClickOnce application is not a normal application with a simple executable
- ClickOnce application does not accept normal command-line arguments
- ClickOnce application must be installed using a special application link
- ClickOnce application requires special mime-types in IIS
- ClickOnce application has slow startup when checking for updates
So I liked the ClickOnce update story but I hated that a ClickOnce application is special. So, I created an extremely simple updater with the goal of having the least code possible. My simple updater does the following:
- SimpleUpdater can check for updates at startup (in a separate thread for speed) or anytime on demand
- SimpleUpdater downloads very simple remote XML manifest
- SimpleUpdater will prompt user when there is an update available
- SimpleUpdater downloads and extracts updated files and restarts updated application
SimpleUpdater is built with and requires the .NET 3.5 Client Profile.
- Add Updater.exe to your project
- Add Updater.cs code to your project
- Add UpdateForm to your project
- Call CheckForUpdates upon startup
- Add ShowUpdateDialog code to your main form
- (optional) Add manual check for update option to your main form
- Create and upload manifest and update zip to server
Update: I've added an example client app to thegithub
Step 1: Add Updater.exe to your project
Add the Updater.exe to your project and set build output to content and copy to output directory to copy if newer. The Updater.exe becomes another file that is deployed with your application.
Step 2: Add Updater.cs and UpdateForm to your project
Copy these files into your project. The UpdateForm is so simple that if you need to rewrite in XAML it should only take a few minutes. Feel free to change the naming and namespaces to simplify things.
Also, add the following settings to your project (or hard-code if you like):
Step 3: Add startup code
Upon startup, usually in your Program.cs Main() method, call Updater.UpdateUpdater() to check for a new Updater.exe file. Since the Updater.exe file was locked during update, the client app must rename the file.
Next, in your main form's load event, use a thread to call Updater.CheckForUpdates().
Step 4: Add ShowUpdateDialog method to your main form
This code will extract the update details from the manifest document and show the UpdateForm as a dialog.
Step 5: (optional) Add manual check for update
If the user does a manual check from the help menu, you may want to display a message box with the result. Use this code:
Step 6: Create a manifest file
The App.manifest is extremely simple. It contains the update date, version, and links:
I recommend you add this file to your project and set "build output" to "content" and "copy to output directory" to "copy if newer". Also, you can either automate the update of this file with each build or update it manually. Each time you want to deploy an update, update the assembly version and update this manifest file.
Step 7: Deploy the update
Build your application and create a zip of the release files. Copy the zip file and the manifest file to your server.
Simple Updater Source Code
I've put the simple updater source code on GitHub. The updater application includes some code from the SharpZipLib for unzipping files. Otherwise, the code is pretty simple. I wrote around 200 lines of code for the updater application.