Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Use Webclient to Make An Auto Updater

0.00/5 (No votes)
17 Sep 2014 1  
To make a simple auto updater demo, I use webclient 'interfaces' to download the file and monitor the progress.

Introduction

This tip provides a cheap method to download file via a URL.

Background

Most programs like to provide the auto update function so that end users can get the best user experience. In simple words, auto update can be finished only in two steps:

  • Step 1: Visit the program server to check whether there is a new version available.
  • Step 2: Ask user whether to update and follow the user's select.

This tip will mainly describe the workflow around those two steps above. This is my work experience. If there is any problem, you can leave a message.

Using the Code

1. Get the newest version information on the server.

In most cases, a program has a version number such as 1.20.11. It's a series of num divided by '.'. When checking whether the server's newest version is newer than the user's current version, the version number is a convenient method. In general, we consider version 1.20.22 is newer than version 1.20.11.

In my program, I use INI file to record the version information. In the program's install directory, there is a file named Update.ini. This file's content is simple:

[Update]

CurrentVersion = 1.10.12

IniPath = ftp://192.168.29.19//Version.ini

There are two data lines in it. The "CurrentVersion" represents the program version and the "IniPath" represents the server INI file path. We can download the Version.ini and read its version number to make a comparison in order to check whether to inform the user.

The Version.ini on server is:

[Update]

CurrentVersion = 1.11.00

ExePath = ............

The first data line represents the server's newest version num and the second list represents the download path.

How to download the file will be represent later, I will show how to compare two Version numbers:

     /** 
     *  
     * @param version1 
     * @param version2 
     * @return if version1 > version2, return 1, if equal, return 0, else return -1 
     */  
    public static int compare(String version1, String version2)
    {  
        if (version1 == null || version1.Length == 0 || version2 == null || version2.Length == 0 )
        {
            return -1;
        } 
        int index1 = 0;  
        int index2 = 0;  
        while(index1 < version1.Length && index2 < version2.Length)
        {  
            int[] number1 = getValue(version1, index1);  
            int[] number2 = getValue(version2, index2);  
              
            if (number1[0] < number2[0]) return -1;  
            else if (number1[0] > number2[0]) return 1;  
            else 
            {  
                index1 = number1[1] + 1;  
                index2 = number2[1] + 1;  
            }             
        }  
        if(index1 == version1.Length && index2 == version2.Length) return 0;  
        if(index1 < version1.Length)   
            return 1;  
        else  
            return -1;  
    }  
     /** 
     *  
     * @param version 
     * @param index the starting point 
     * @return the number between two dots, and the index of the dot 
     */  
    public static int[] getValue(string version, int index) 
    {  
        int[] value_index = new int[2];  
        StringBuilder sb = new StringBuilder();  
        while(index < version.Length && version.ElementAt(index) != '.') 
        {  
            sb.Append(version.ElementAt(index));  
            index++;  
        }  
        value_index[0] = Convert.ToInt32(sb.ToString(),10); 
        value_index[1] = index;  
          
        return value_index;  
    }  

The code will divide the version string by the character ‘ .’. Compare each number you get from the string.

2. Download the file from the server.

As the title mentioned, this tip will introduce download with the 'Interface' webclient. It provides plenty of methods for downloads.

The webclient has synchronous and asynchronous method. The synchronous method will block the process. It is usually used for downloading small files which won't take so much time to download. In our case, we use synchronous method to download the INI file from the server. The code is as follows:

// New a webclient object
    WebClient web  = new WebClient();

//Download synchronized 

try
{
     string UserName = AutoUpdate.Form1.GetStringFromFile("UpdateInfo", "ID_USER_NAME");
     string PassWord = AutoUpdate.Form1.GetStringFromFile("UpdateInfo", "ID_USER_PASSWORD");
     web.Credentials = new NetworkCredential(UserName, PassWord);
     web.DownloadFile(new Uri(ServerIniPath.ToString()), ItemSavePath);        
}
catch (System.Exception ex)
{                  
     throw ex;
} 

We can get the newest program download path from the INI file, if we need to download it, we can use the asynchronous method.

try
{
    web.DownloadFileAsync(new Uri(DownLoadAddress), ItemSavePath);
    web.DownloadProgressChanged += client_DownloadProgressChanged;
    web.DownloadFileCompleted += client_DownloadFileCompleted;
}
catch (System.Exception ex)
{
    throw ex;
}

In the code, we can see after calling the download method, we also add two event handlers for it. These two handlers help us to know the download detail information, such as the percentage downloaded, how many bytes are downloaded and so on. The detail handler code is as follows:

void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
   Action<AsyncCompletedEventArgs> onCompleted = progressCompleted;
   onCompleted.Invoke(e);
}

void client_DownloadFileProgresschanged(object sender, AsyncCompletedEventArgs e)
{
   Action<DownloadProgressChangedEventArgs; onCompleted = progressChanging;
   onCompleted.Invoke(e);
}

The method progressCompleted and progressChanging can be written as your demand.

3. Download exceptions.

This exception is not the one caught by try and catch. This is the real exception: the Internet is unavailable, user cancels the update, the server is unavailable. Because we use the asynchronous method, there will be plenty of concurrent problems. I will display how I handle some of them.

The Internet is unavailable.

This problem may happen at any time, so I have to start another thread to check Internet state by time. Once I find that the Internet is down, I will call the download process to inform user.

How to check the Internet is available is easy, we can use the method provided by "wininet.dll".

 [DllImport("wininet.dll")]
  public static extern bool InternetGetConnectedState(out int lpdwFlags, int dwReserved);

The user cancels the download:

The webclient considers this case. It provides the cancel method to stop download and the dispose method to release the resource the download process used.

Done.

History

  • 17th September, 2014: Initial version
  • 18th September, 2014: Uploaded sample code

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here