Adding “Check for update” feature to your C# application

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 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"?>

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;
// 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
// 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;
// for text nodes...
if ((reader.NodeType == XmlNodeType.Text) &&
// we check what the name of the node was
switch (elementName)
case "version":
// thats why we keep the version info
// in format
// the Version class does the
// parsing for us
newVersion = new Version(reader.Value);
case "url":
url = reader.Value;
catch (Exception)
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 =
// 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,
// navigate the default web
// browser to our app
// homepage (the url
// comes from the xml content)

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.


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

40 thoughts on “Adding “Check for update” feature to your C# application”

  1. Thanks for the sample. Easy to follow. i have one question: Say i want to update the version number in that XML file automatically when i make an update. How can i have the project plug the latest version into the file for me? Is it possible?

  2. Hi Joe,
    That’s an interesting topic you mentioned. To make it short: you can write you own (very simple) tool and attach it to the post-build event.

    In Visual Studio you can use project build events to run your own console tool (f.e. publish.exe “$(TargetPath)”). This tool should open the compiled executable (the path is passed as a command line argument) and determine its version (you can use as a starting point). At the end the tool should create a new xml containing the current version number (and optionally upload both the executable and the xml to your web server). Hope this helps.
    One more thing to mention: I don’t think that every version of the application that compiles without errors should be published, it should be tested first 🙂 So it’s a good idea to create a new project configuration (called Publish and based on the Release configuration) and attach the tool I mentioned only in this config build events. In every day compiling you should use Debug/Release configurations and when you want to release the new version you should use Publish.

  3. Thanks for the response mech. i haven’t quite got the hang of Publishing yet, as the application is small and in-house only. It would only be published to a network share. But you’re absolutely right, compiles != works. Since it’s still a small enough app, i do the testing myself in the VS environment. i suppose as it grows i’ll need to take your advice on a second build config. i’ll check into that link and see what i come up with.

    Thanks again!

  4. Question – how to do the actual update? If your patcher is launched from within the main app, how do you overwrite the files during run time? Also, for projects with multiple files (an exe, .config, and dlls) would you have a version.xml for all of them, or would you keep them all in one file?

  5. Hi

    I’ve assumed the simplest scenario here – our program just checks for the new version and allows user to download the installer for it. This solves the problem of multiple files.
    Of course it would be easier if the application updated itself automatically. If you would like to do this I see two solutions:
    1) Download the installer to the temporary directory. Execute the installer using Process.Start and immediately call Application.Current.Shutdown to end the running program. The installer should install the new version and re-launch our application. I wrote a simple tutorial about creating MSI installers.

    2) If you don’t want to use the installer you can program the process yourself:
    – check if the new version is available
    – copy the current executable to a temporary location, execute it (Process.Start) and terminate the current process. While executing the app from the temporary location you should pass some parameters indicating it should perform an auto update.
    – the new process downloads the new version, replaces the application files (while they are not locked now), executes the new version using Process.Start and terminates
    – the new version should perform a cleanup removing the temporary executable created at the beginning.

  6. I found your site on technorati and read a few of your other posts. Keep up the good work. I just added your RSS feed to my Google News Reader. Looking forward to reading more from you down the road!

  7. Hi guys,
    I’d like to thank you all (Erwin, Joe, Carson and Alex) for your feedback. In fact for the last 2 moths I have a real mess at work with a lot of over hours and because of it I have both – a lot of ideas what I’d like to write about and almost no time to actually write it. All your feedback (being honest I wasn’t expecting any for the first few months) gives me the feeling that writing these articles actually makes sense, cos there are people that find it useful. And your feedback of course gives the motivation to continue the work. So again, thanks to all of you.
    I hope I’ll write another article in till the end of August. Some of the comments (Carson’s in fact) shows that the solution I presented is a very basic one and I fully agree with him. I’d like to explain how to implement ‘Check for update’ in a more advanced way and how to create MSI installers (that we’ll need) using WiX.

  8. Awesome post, Worked perfect! It makes thing so much easier when you can find a strait forward answer to a question. and it doesn’t get any more strait forward than this!

    Thanks again!

  9. Wonderful! Thanks for the help, this was exactly what I was looking for! (well, this and your more detailed download post as well)

    Please keep the posting up! I look forward to reading from your blog in the future.

  10. Great article. 🙂
    I noticed though that you never used a finally block to close the reader in case of an exception occurring.

  11. John,
    Thank you for pointing this out, you are absolutely right – the reader should be closed in both cases – when everything is OK and when an exception occurred during parsing. And try…finally is of course the way to do it. I’ve modified the example to follow your good-practice advice 🙂

  12. Great stuff..! 🙂

    I implemented this in my own application and ran into a small inconvenience. My users are usually connected to their office on Cisco VPN which blocks most web addresses, including the URL where my XML is located. XmlTextReader.MoveToContent will return an exception fairly quickly if there is no network connection at all, but if the user is on VPN it takes about 60 seconds before it errors out.

    So instead of giving XmlTextReader the URL of the XML file, I created an HttpWebRequest with a modest timeout value then used the GetResponseStream with the XmlTextReader.

    # string xmlURL = “http://domain/app_version.xml”;
    # HttpWebRequest hwRequest = (HttpWebRequest)WebRequest.Create(xmlURL);
    # hwRequest.Timeout = 5000;
    # HttpWebResponse hwResponse = null;
    # XmlTextReader reader = null;
    # try
    # {
    # hwResponse = (HttpWebResponse)hwRequest.GetResponse();
    # reader = new XmlTextReader(hwResponse.GetResponseStream());
    # reader.MoveToContent();
    # …
    # }
    # finally
    # {
    # if (reader != null) reader.Close();
    # if (hwResponse != null) hwResponse.Close();
    # }

    Are there any pitfalls with this method that I might be overlooking?


  13. This is really interesting!!! Just what i was looking for 😀
    I was really keen on using ClickOnce but this is much much more easy and neat! I just have to host the XML file somewhere 😀

    Thanx a lot 🙂 🙂

  14. Hello,

    @OverTech: Yes, indeed, HttpWebRequest gives you more tcp/ip control than XmlTextReader does. I’ve checked your code snippet and it seems fine to be, well done 🙂

    @Ranhiru: You should host two files: the XML and your installer for the new version, so users can download it. Luckily there are some free web hosting services that allow you to do so.

  15. I used this code along with a downloader request code, and now the application checks the XML, and if there is an update, will ask if its OK to download it. it will then download it and install the Update. I am planning on adding a “update from USB drive” option that will check the drive for the XML file, and if the version is a newer one, install the update package from the USB drive.

  16. Thanks for the nice article. I found it when I try to make VS publishing and CheckForUpdate work together. Do you have any thought on that?

    By the way, on parsing out the version info from the xml file, it would be much easier using XPath. e.g.
    XmlDocument xmlDoc = new XmlDocument();
    Version version = new Version(xmlDoc.SelectSingleNode(“/ourfancyapp/version”).InnerText);
    string url = xmlDoc.SelectSingleNode(“/ourfancyapp/url”).InnerText;

  17. I get a error here:

    if (reader != null) reader.Close();

    It says “Error use of unsigned local variable “reader”

  18. Steve,
    Your C# compiler seems to be more strict 🙂 Please try initializing the variable before the try…finally block like this:
    XmlTextReader reader = null;

  19. Hey,

    thanks for the tut. I tried this, but only i get it´s an exception. It means, that there is an unexpected xml-declaration. It must be the fist node of the xml – doc. I don´t know what to do.

  20. pls can i know how to cet version number of my older application and the new application so that it could be able to download the new application and install it. i dont know much about how to deal with version numbers.

  21. Mech,

    First of all, thank you so much for the tutorial. It will make my apps much more manageable.

    I have one question:
    The place where I store my updated files is secured with an htaccess password. Is there a was to incorporate that securability in this tutorial?

  22. Matthew, I’m not sure if you are protecting the xml file containing the newest version information or the installer itself. Anyway, you should pass the credentials to the reader. In case of the xml file, here is the example: And here is the basic authentication for the WebRequest (used to dowload the installer:,guid,11609e8d-e0fc-41f4-83a2-6e8ea46339f6.aspx). Those topic are not covered by this tutorial in order to keep it simple. Securing the installer or version info with basic auth isn’t a common thing. The downside is that you have to hardcode the credentials in your app. And when someone is using a proxy, he can intercept the request and response, so it’s not secure.

  23. Wow just what I was looking for. I did get one build error in C#VS 2010 though.

    if (reader != null) reader.Close();

    Returns an error that reader doesn’t exist in the current context.

    To fix I just changed:
    XmlTextReader reader;
    XmlTextReader reader = null;

  24. How to incrementally update files? For exampe, I need to update some text files. I know there is a new version available. How do I manage only the new content on the server and update my local files?

    Thanks. 🙂

  25. First off, hey thanks Mech, really handy stuff here mate good job 😉

    So this works really well… But what if someone was to use this process for more than one application using the same XML file?

    Using this:

    Works great, but what if we don’t want to make a new XML file every time we make a app, we rather keep one XML file and store all app updates on it like this:

    But doing this, it wont work with the above source as its not going into the XML files specific Name: ourfancyapp

    If we use this:

    It also doesn’t work… Anyway you can give an example so it supports more than one app?

    Also, i thought in xml, the correct declaration approach is :
    not “utf-8” both should technically work fine but the recommended markup is “UTF-8”?

    Could you please give an example and add support of more than one app?


Leave a Comment