Online Update #1 - Check For Updates

Category: Application Features

Date: 03-28-2012

Return to Index


 
'Allowing a user to download a new version of software is very common. Here's one way to do it,
'based on using the URLDownLoadToFile API. This approach does not provide download status information.
'See the snippet http://gbl_00050 For a second approach that uses the TCP capabilities of PowerBASIC.
 
'This approach only addresses online updating of the application EXE.  As written, it does not
'include code to download secondary/support files.
 
'The approach is pretty simple, requiring only the following steps:
'1. Place your latest EXE on your server, renamed as "yourapp.new". Using .new for an
'   extension bypasses download constraints on downloading files with .EXE extensions
'   and avoids downloading a file with the same name as your application.
 
'2. On your server, place a text file which contains a single line, containing only the
'   version/build number of the latest EXE. Name it "yourapp.ver".
 
'3. In your app, place a menu item (I suggest Help\CheckForUpdates) which calls the
'   CheckForUpdates procedure given below.
 
'4. Run "CheckForUpdates" - it will download "app.ver", read the content, and compare the local
'   and server EXE versions. If a newer version is on the servers, and the user agrees, the function will
'   download the latest version of "yourapp" (a file called "yourapp.new"). CheckForUpdates also deletes, if
'   they exist, the files "yourapp.exe.old" and "yourapp.new", to make room for the new downloadable version.
'   CheckForUpdates then starts a second application, gbOnlineUpdate, passing it the name of the application
'   to be updated plus the position/size for displaying gbOnlineUpdate.
 
'gbOnlineUpdate source code is included in snippet http://gbl_00051. Put the gbOnlineUpdate.exe
'file in the same folder as your application EXE.
 
'One final note: this approach uses the DownLoadURLToFile API to download files. The API does
'not provide download progress information.
 
 
'Primary Code:
'To initiate an online update, a single procedure is all that must be added to your application. That
'procedure includes a local variable containing the current version/build# of the application.
'Because of length, the CheckForUpdates procedure is shown only once, in the compilable example below.
 
 
'Compilable Example:
'This code uses a menu item under HELP to call the CheckForUpdates routine.  The routine verifies that
'a new version of the application is available from the server, downloads the new version file, and starts a
'second program called gbOnlineUpdate. The second program, gbOnlineUpdate, backs up the original EXE by
'renaming it as xxx.exe.old, then renames the download file as xxx.exe and optionally restarts the new program.
#Compiler PBWin 9, PBWin 10
#Compile EXE
#Dim All
#Include "Win32API.inc"
#Include "CommCtrl.inc"
#Include "WinINET.inc"
%ID_MenuHelpCheckForUpdates = 100 : %ID_DownloadTimer = 300 : %ID_Label = 400
Global hDlg As Dword, hMenu As Dword, hMenuHelp As Dword, hWait as Long
 
Function PBMain() As Long
   Dialog New Pixels, 0, "Test Code",300,300,200,200, %WS_OverlappedWindow To hDlg
   Control Add Label, hDlg, 500, "I am the original EXE", 20,20,140,20, %WS_Border Or %SS_Center
   AddMenu
   Dialog Show Modal hDlg Call DlgProc
End Function
 
CallBack Function DlgProc() As Long
   If CB.Msg = %WM_Command AND CB.Ctl = %ID_MenuHelpCheckForUpdates Then CheckForUpdates
End Function
 
Sub AddMenu
   Menu New Bar To hMenu
   Menu New Popup To hMenuHelp
   Menu Add Popup, hMenu, "&Help", hMenuHelp, %MF_Enabled
   Menu Add String, hMenuHelp, "&Check For Update", %ID_MenuHelpCheckForUpdates, %MF_Enabled
   Menu Attach hMenu, hDlg
End Sub
 
Sub CheckForUpdates
   Local ServerVer$, Style&, URLPath As Asciiz*%Max_Path, LocalPath As Asciiz*%Max_Path, pid???
   Local x As Long, y As Long, h As Long, w As Long, LocalVer$, app$, iResult&, wX As Long, wY As Long
 
   app$ = "app"     'the name of your application, without the EXE - use lowercase!
 
   URLPath = "http://www.garybeene.com/files/" + app$ + ".ver"    'use your own server information (mine does have app.ver for your use)
   LocalPath = Exe.Path$ + app$ + ".ver"
   LocalVer$ = "5.1"               'use a string representing a numerical value
 
   'get the .ver file from the server. if cannot get it tell user there was a problem and then exit sub
   iResult& = DeleteURLCacheEntry(URLPath)  '1 = success  clear the cache
   If URLDownloadToFile (ByVal 0, URLPath, LocalPath, 0, 0)  Then
      MsgBox "Update information not available!", %MB_Ok Or %MB_IconInformation, "Online Update"
      Exit Sub
   End If
 
   'check if server version is newer. if not, tell user and then exit sub
   Open Exe.Path$ + app$ + ".verFor Input As #1
   Line Input #1, ServerVer$  'get version of app that is on the server
   Close #1
   If Val(ServerVer$) <= Val(LocalVer$) Then   'check to see if the server version is newer than the local version
      MsgBox "You have the latest update!"
      Exit Sub
   End If
 
   'server version is newer than local version
   'ask user for permission to proceed with download of "app.new"
   Style& = %MB_OkCancel Or %MB_IconQuestion Or %MB_TaskModal
   If MsgBox ("Update available. Download and install?", Style&, "Online Update") = %IDCancel Then Exit Sub
 
   'before downloading, remove the existing .old and .new files, if they exist
   If IsFile(Exe.Path$ + app$ + ".exe.old") Then Kill Exe.Path$ + app$ + ".exe.old"  'kill .old to clear the way
   If IsFile(Exe.Path$ + app$ + ".new") Then Kill Exe.Path$ + app$ + ".new"          'kill .new to clear the way
 
   'now download the new version to same folder as the application
   URLPath = "http://www.garybeene.com/files/" + app$ + ".new"  'get the new app from the server
   LocalPath = Exe.Path$ + app$ + ".new"  'download as app.new
 
   iResult& = DeleteURLCacheEntry(URLPath)  '1 = success  clear the cache
 
   'Display PleaseWait ... dialog
   Dialog Get Client hDlg To w,h
   wX = 150 : wY = 60
   x = (w-wX)/2    'gets left position of WaitDialog to center over app
   y = (h-wY)/2    'gets top position of WaitDialog to center over app
   Dialog New Pixels, hDlg, "", x, y, wX, wY, %WS_Popup To hWait
   Control Add Label, hWait, %ID_Label, "Please wait ... ", 0, 0, wX, wY, %SS_Center Or %SS_CenterImage Or %WS_Border
   Control Set Color hWait, %ID_Label, %Black, %White
   Dialog Show Modeless hWait
 
   If URLDownloadToFile (ByVal 0, URLPath, LocalPath, 0, 0)  Then
      Dialog End hWait
      'download failed. tell the user then exit sub
      MsgBox "Download of updated version of App failed!", %MB_Ok Or %MB_IconInformation, "Online Update"
      Exit Sub
   Else
      Dialog End hWait
      'the new application was successfully downloaded, so start gbOnlineUpdate.EXE, passing app.exe
      'dialog dimensions /top /left /width /height are passed so gbOnlineUpdate can be centered on currently running app.EXE
      'then close app.EXE
      Dialog Get Loc hDlg To x,y : Dialog Get Size hDlg To w,h
      pid??? = Shell (Exe.Path$ + "gbOnlineUpdate.exe  " + app$ + " " + Str$(x) + " " + Str$(y) + " " + Str$(w) + " " + Str$(h))
      'note: use 1 or more spaces to separate gbOnlineUpdate command line arguments
      Sleep 350   'strictly for effect - gbOnlineUpdate appears briefly on top of app
      Dialog End hDlg  'quit this application - gbOnlineUpdate is now running
   End If
 
End Sub
 
'gbs_00050
'Date: 03-10-2012


created by gbSnippets
http://www.garybeene.com/sw/gbsnippets.htm