Today I decided I would add a ‘check for update’ option to my Eyes Relax application. This is quite useful feature, especially when you host your application on many hosting servers (like download.com and others). In this case it can be difficult for the user to check if there is a newer version of your software available, because:

  • the user does not remember where he downloaded the application from
  • there is an older version on the hosting server, so the user is not aware that there is a newer version of your app available
  • simple, but very common reason: the user is too lazy to look for the new version :P; and because it’s easier to simply select the ‘update’ option in your application, it may work for lazy users

Beside those reasons this is a nice, small feature we can practice our c# programming skills on :). At least for me, because I’ve spent last two years mainly developing server modules in Python. Two major subjects are:

  • HTTP file downloading
  • simple XML parsing (XmlTextReader)

Let’s start.


General idea

First we need a way to provide our application with the information about the newest version. So what we do is put a little xml file anywhere on Internet (well, preferably on your homepage). In this xml file we store the number of the newest version of our app. While checking for update we download this xml, parse it and compare the version of running application with the version from the xml file.

Downloading the xml file

This is very easy – we just provide the XmlTextReader with the URL of our XML file. The XmlTextReader will download the file for us. What’s even better, it uses the .NET 2.0 internal solutions that detect the IE proxy settings (I’ve double-checked this and it really works :)), so this will work even when the user connects through a proxy.

Parsing the xml

As mentioned above, we will use XmlTextReader (just remember to use System.Xml). First take a look at our litte xml contaning the information about the newest version:


<?xml version="1.0" encoding="utf-8"?>
<ourfancyapp>
  <version>1.2.3.4444</version>
  <url>http://some.domain/our_app_homepage/</url>
</ourfancyapp>

As you probably noticed we store the version information in the same string format as c# Application.ProductVersion. I’ve chosen this format because it will be easier to parse and compare the version numbers, as you will see later.

Ok, let use XmlTextReader to parse the xml:


// in newVersion variable we will store the
// version info from xml file
Version newVersion = null;
// and in this variable we will put the url we
// would like to open so that the user can
// download the new version
// it can be a homepage or a direct
// link to zip/exe file
string url = "";
XmlTextReader reader;
try
{
 // provide the XmlTextReader with the URL of
 // our xml document
 string xmlURL = "http://domain/app_version.xml";
 reader = new XmlTextReader(xmlURL);
 // simply (and easily) skip the junk at the beginning
 reader.MoveToContent();
 // internal - as the XmlTextReader moves only
 // forward, we save current xml element name
 // in elementName variable. When we parse a
 // text node, we refer to elementName to check
 // what was the node name
 string elementName = "";
 // we check if the xml starts with a proper
 // "ourfancyapp" element node
 if ((reader.NodeType == XmlNodeType.Element) &&
     (reader.Name == "ourfancyapp"))
 {
  while (reader.Read())
  {
   // when we find an element node,
   // we remember its name
   if (reader.NodeType == XmlNodeType.Element)
    elementName = reader.Name;
   else
   {
    // for text nodes...
    if ((reader.NodeType == XmlNodeType.Text) &&
        (reader.HasValue))
    {
     // we check what the name of the node was
     switch (elementName)
     {
     case "version":
      // thats why we keep the version info
      // in xxx.xxx.xxx.xxx format
      // the Version class does the
      // parsing for us
      newVersion = new Version(reader.Value);
      break;
     case "url":
      url = reader.Value;
      break;
     }
    }
   }
  }
 }
}
catch (Exception)
{
}
finally
{
  if (reader != null) reader.Close();
}

That’s how we parse our XML. Now we check if the newVersion and url are not empty. If they’re not, it means we successfuly downloaded and parsed the xml file and now we can…

…compare the versions

The Application.ProductVersion is just a string, and it’s usually not sensible to compare strings containig numbers. Luckily in the .NET executing assembly there is a variable, which happens to be the same type as our newVersion. It makes the comparing a lot easier :) :


// get the running version
Version curVersion =
 System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
// compare the versions
if (curVersion.CompareTo(newVersion) < 0)
{
 // ask the user if he would like
 // to download the new version
 string title = "New version detected.";
 string question = "Download the new version?";
 if (DialogResult.Yes ==
  MessageBox.Show(this, question, title,
                  MessageBoxButtons.YesNo,
                  MessageBoxIcon.Question))
  {
   // navigate the default web
   // browser to our app
   // homepage (the url
   // comes from the xml content)
   System.Diagnostics.Process.Start(url);
  }
}

If the user answers ‘Yes’, we navigate the default browser to the URL we have from the downloaded xml file. I didn’t hardcode this URL in the code, because when we for example move our homepage, we would be in trouble. And in our solution we can simply change the url in the xml file and the users would be automatically directed to the new homepage.

Well, that’s all. As you see this was a pretty simple task. Hope you found it useful.

Enjoy,
mech

P.S. I wrote two more tutorials regarding this topic:

They both show how to implement ‘check for updates’ in a more mature way. You can also download the sample project