User ID:
Password:
Remember Me:
Forgot Password?
Not a member?
Click here for more information and to register.

    Online Updates with VB.NET



    Introduction

    Programmers often split larger applications into smaller, manageable DLLs. Often, shortly after release one or more of the DLLs show minor problems and require bug fixes. However, it is not always easy to get the bug fixes to all the software users. Fortunately, in today's workplace, almost everyone has some connection to the Internet. You are going to look at using this connection to deliver an update.

    As difficult as it sounds, I soon found out after been tasked to write an auto updater for some of our larger applications, that it's reasonably simple. There is simply a short list of tasks to follow, and everything needed is already included in .NET.

    1. Check for an active Internet connection.
    2. Check whether there are updates available for this application.
    3. Download the files to their respective locations.
    4. Start the updated application.

    The Code

    First, you need to set a few defaults and locations.

    'Project name
    Public Const AppName As String = "Hex Editor"
    
    ' Unique Project ID --
    Public Const UpdateID As String = "HexEdit"
    
    ' The Application's Root Path "C:\Dir1\Dir2" (No trailing backslash)
    Public Const AppPath As String = "C:\Program Files\Hex_edit"
    
    ' The Application's Exe "Dir3\Prog.exe" (from the root path.
    ' No leading Backslash)
    Public Const AppEXE As String = "Hex_edit.EXE"
    
    ' Other startup defaults
    ' Last update loaded...
    Public Const LastUpdate As Integer = 0
    ' Wait time to connect to Update Site in seconds
    Public Const TimeOutlen As Integer = 60
    ' Default site to download updates from
    Public Const UpdateSite As String = "updates.mysite.com"
    

    Because the Auto Updater is written as a general application, and you want to be able to add it to any project without having to modify large blocks of code, anything that is specifically related to the project is stored in variables.

    The above defaults relate to first time usage, and should be stored in a file or the Registry. This I will leave up to you to decide where to store the info.

    Your first task is to check whether you have an open connection to the Internet. For that, you add a Standard WebBrowser object to your form. And, make it reasonably large enough to hold relevant details about the update site. By using the WebBrowser, you can automatically use the details set in Internet Explorer to connect to the Internet, and not hassle the user for details about gateways, proxies, and firewalls. The WebBrowser also has a Document Completed event that will trigger when the page has completed loading.

    The website that will be hosting the updates will have two requirements:

    First, the default page must always stay with the same name. You can alter the page content, but keep the name constant. Second, use a Fixed Page Title to identify the page. Once the page has completed loading, you use the Document Title to verify that you are at the right site.

    Private WithEvents Timer As Windows.Forms.Timer
    Private TimeDelay As Integer    ' Timeout in seconds
    Private HttpWait As Boolean     ' Wait for Http page to load
    Private Retry As Boolean        ' Retry to load failed connection
    Private TimeOut As Boolean      ' Wait has timed out
    Private Canceled As Boolean     ' Cancel button Clicked
    Private Closeme As Boolean      ' Close the form
    Private Updated As Boolean      ' Files were updated
    
    Private Sub WBData_DocumentCompleted(ByVal sender As System.Object, _
    ByVal e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) _
       Handles WBData.DocumentCompleted
       HttpWait = True
       If WBData.DocumentTitle.ToUpper <> "MY UPDATE SITE" Then _
          TimeOut = True
    End Sub
    
    Private Sub Timer_Tick(ByVal sender As Object, _
       ByVal e As System.EventArgs) Handles Timer.Tick
       If TimeDelay = 0 Or Canceled Then
          TimeOut = True
          Timer.Enabled = False
       Else
          TimeDelay -= 1
       End If
    
    End Sub
    
    Private Sub Cancel_Click(ByVal sender As System.Object, _
       ByVal e As System.EventArgs) Handles Button3.Click
       Canceled = True
    End Sub
    
    Private Sub StartUpdate()
       Dim Updaterfile As String
       Dim Serverfile As String
       Dim TotalUpdates As Integer
       Dim LastUpdate As Integer
       Dim msgresult As MsgBoxResult
    
       Me.Show()
       LblText.Text = "Connecting to Remote Server" & vbCrLf & _
       "Please ensure that your internet connection is active"
       Me.Refresh()
       WBData.Url = _
          New System.Uri("http://" & UpdateSite & "/Default.html")
       HttpWait = False
       TimeDelay = TimeOutlen
       Timer = New Windows.Forms.Timer
       Timer.Interval = 1000
       Timer.Enabled = True
       While Not (HttpWait Or TimeOut Or Canceled)
          System.Windows.Forms.Application.DoEvents()
    .................
    

    As you can see, when the document has completed loading you check whether the document title matches your preset title. If the title does not match, you have not connected successfully to your update site. You also have a countdown timer running to make sure that you don't wait too long for a connection. Just remember: The more complex your web page, the longer to load it. So, keep you update web page small.

    You also have a cancel button on your form so that, if the user does have a slow Internet connection, or just does not want to worry about the update right now they can skip the update. From here, quickly jump to Task #4, starting the application. Why jump ahead? At this point, you may need to start the application without ever completing an update check. The update could be cancelled or timed out, so you want to start the main application.

    Private Sub AutoUpdater_FormClosing(ByVal sender As Object, _
       ByVal e As System.Windows.Forms.FormClosingEventArgs) _
       Handles Me.FormClosing
       If Not Closeme Then
          e.Cancel = True
       End If
    End Sub
    
    Private Sub LoadApp()
       Shell(AppPath & "\" & AppEXE, AppWinStyle.NormalFocus)
       Closeme = True
       Me.Close()
    End Sub
    

    Here, you simply use the Shell command to start the main application and exit the updater. Not much more can be said for this task. However, many may ask, "Why not do all this within my main application?" If you late bound just about everything in your application I'm sure you could; however, you still would not really be able to update the primary EXE file of the project. Using a second application to update and run the main application gives you the ability to update just about everything in a single pass and start the application without the need to stop and restart.

    Now that loading the Main Application is taken care of, get back to what happens when the Connection times out, or the user clicks Cancel.

    ...........
       If TimeOut Then
          LblText.Text = "Connection to Remote Server Failed" & _
          vbCrLf & "Application will continue in 10 seconds"
          Button1.Enabled = True
          TimeOut = False
          TimeDelay = 10
          Timer.Interval = 1000
          Timer.Enabled = True
          Retry = False
          While Not (TimeOut Or Retry Or Canceled)
             System.Windows.Forms.Application.DoEvents()
          End While
          If Retry Then
             LblText.Text = "Reconnecting to Remote Server" & _
             vbCrLf & " Please ensure that your Internet connection _
                        is active"
             Button1.Enabled = False
             TimeOut = False
             HttpWait = False
             TimeDelay = TimeOutlen
             Timer.Interval = 1000
             Timer.Enabled = True
          Else
             LoadApp()
             Exit Sub
          End If
       End If
    End While
    ...............
    

    Inside the While Wend loop, you check whether a timeout occurred. If so, you give the user an opportunity to retry; if the user decides against retrying to connect, of the retry timer runs out, you simply open the Main application and exit. By putting your retry code within the original Timeout loop, the user can have multiple retries at connecting to the server.

    Now, you are at the point where you've successfully connected to the Internet and contacted your Update site; the user has not clicked Cancel. You want to check whether there are outstanding updates for this application. The easiest method I found to do this was simply by downloading a file, using the Unique UpdateID constant that you set earlier.

    ...............
    If Not Canceled Then
       LblText.Text = "Connection to Remote Server completed" & _
       vbCrLf & " Please wait while checking for new updates"
       GBLbl.Refresh()
       Updaterfile = AppPath & "\UpdateLog.xml"
       Serverfile = "http://" & UpdateSite & "/" & UpdateID & ".XML"
       Try
          If File.Exists(Updaterfile) Then File.Delete(Updaterfile)
          My.Computer.Network.DownloadFile(Serverfile, Updaterfile)
    ................
    

    About the Author

    Richard Newcombe has been involved in computers since the time of the Commodore 64. Today, he has excelled in programming, and designs. Richard is in his mid 30's and, if or when you looking for him look no further than his computer. Always willing to help and give advice where he can in regard to computer related subjects. At present he is working as a .NET 2008 Software Developer for Syncrony Web Services, South Africa.

    Downloads

  • AutoUpdateDemo.zip

  • IT Offers


    Top Authors