Home > .NET Code Samples, Windows Home Server > How to implement an update check in your Windows Home Server AddIn

How to implement an update check in your Windows Home Server AddIn

March 21st, 2010

So you’ve written your Windows Home Server AddIn, made it available for download and are happy that people all over the world start using it on their Windows Home Servers. But shortly after you’ve put your work out in the wild users send you emails or start complaining on WHS related forums about weird behavior of your addin or WHS console crashes. You look at your code again, determine the culprit, fix the bug and compile a new version of your addin and put it in the download section of your website or blog. But how can you notify all users of older versions of your software about the availability of the new bugfix release? Of course the easiest way to do this is by having your addin check for available updates from time to time.

I want to show you the simplest form of an update check in less than 20 lines of C# code. Before we can have a look at the code we have to ask ourselves which steps are required to perform:

  1. Determine the version of our addin that is currently running
  2. Retrieve information about the latest version of our addin from the web
  3. Compare these two versions and decide whether the currently running version is outdated
    Step one is fairly easy: By the use of System.Reflection.Assembly we can determine the version of the assembly the currently executing code resides in like so:
    // Determine the Version of your addin by getting the assembly version
    // of the assembly that contains the code that's currently being executed.
    Version currentVersion = Assembly.GetExecutingAssembly().GetName().Version;

Before we can implement Step 2 we have to decide how and where we want to store the version information of out addin on the web. For this example we simply create a single-line text file (.txt) with the version number of our latest addin build:

image

Next we place this file on our web space so that our addin can retrieve it from there. For instance the URL to the file could be http://ourwhsaddin.com/OurAddInVersion.txt.

Now we can write the code that will download the version information file and parse its contents:

// URL of the file containing the version number of the latest available
// version of your addin
String versionURL = "http://ourwhsaddin.com/OurAddInVersion.txt";

// Prepare the HttpWebRequest object for downloading the version information
// file
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(versionURL);
// Set the current addin + version number as user agent so that
// the web server logs it as the "user's browser"
req.UserAgent = "My WHS AddIn Version " + currentVersion.ToString();
// Set the cache policy so that the version informatin file is always
// downloaded and not retrieved from the local cache.
req.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
// Get the version information file by executing the web request
WebResponse resp = req.GetResponse();
Version availableVersion;
using (StreamReader sr = new StreamReader(resp.GetResponseStream())) {
    // Read and parse the version information
    string availableVersionString = sr.ReadLine();
    availableVersion = new Version(availableVersionString);
    sr.Close();
}

As you probably know web servers usually log all activity for hosted content like client IP addresses, users’ web browsers (= User Agent) locations of accessed files and so on. If you want to be able to determine which versions of your addin are performing update checks you can set the addin name and current version as user agent (see above) and you will find this information in your server logs.

The code above is pretty self-explanatory (I think). We create System.Net.HttpWebRequest object from our version file URL, set the user agent string and cache policy and execute the request by calling GetResponse() on it. We then set a System.IO.Streamreader on the response stream and read the first (and only) line from the stream (= our version information file). The next step is to convert the version string into a System.Version object by creating a new System.Version object passing the version string to the constructor.

So we have the version of our currently running code in currentVersion and the version of the latest available release in availableVersion. Our last step (Step 3) is to compare these two in order to determine whether the latest release is newer than what’s currently running:

if (availableVersion > currentVersion) {
    // A new version is available for download

}

Tadaa! That’s it! Of course you’d have to do proper exception handling which I omitted from the example in order to make the code look simple and clean.

Like I said this is the most basic form of an update check mechanism. Instead of downloading a simple text file we could set up a web service and submit more information about the current addin version when we call it. But be sure that you respect the user’s privacy, when doing this! We could also include the download URL and version history in the text file (or the web service response) and display it to the user when we notify them about the availability of an update. The possibilities are endless!

While it’s a nice feature to get update notifications I believe it would be best if the operating system would handle this and users would have a central place where they can go to update their software. However, Windows Home Server does not have such a place but the upcoming AddIn Central from HomeServerLand looks very promising and I hope that it will become this central place of addin administration.

UPDATE:

I just got notified by Björn Bürstinghaus that they are still looking for beta testers for the german version of AddIn Central. If you speak german and want to participate in the beta please visit http://blog.buerstinghaus.net/add-in-central-beta-fur-den-home-server/ and leave a comment. You’ll then be contacted by the AddIn Central team via email.

  1. No comments yet.
Comments are closed.