Consultancy and Programming
Advice, tips, techniques and downloads for Visual Foxpro developers.
The Software Update Wizard, from Power Programmer, is a tool for adding "over the web" updating to your software applications. You can use it to check for new versions of your executables, and to install these on your users' systems. The Wizard is a commercial product: it's not free, but it's not all that expensive either.
In this article, we will give you an overview of the product's features, and show you how to integrate it with a Visual FoxPro application. This is a fairly painless process, but there are a few points to watch out for. In most cases, you will only need to write a few lines of code. You will also need to create a script file to control the operation.
Note that this article is based entirely on our own experience of the product, and should not be regarded as "official" documentation. We have no connection with Power Programmer, nor do we have any financial interest in the product.
If you develop large software applications with a dispersed user base, you will know how difficult it can be to keep your users up to date with your latest versions. You can send out updates by email, or point users to a website from where they can download the necessary files. But both these options are time-consuming and inconvenient, and they put the onus on the user to take the necessary action.
A better system is one where the software itself checks for updates. It might do this on demand, or it might do it automatically every time the program is loaded. Either way, it should immediately retrieve any updated components that it finds, and install these with the minimum of effort on the user's part.
This is exactly what the Software Update Wizard achieves. You point it to a web site that contains the updated files. The wizard checks the files against those already on the user's system, downloads any that need updating, and copies these to the target folder. You can arrange for it to do the whole thing silently, or you can tell it to prompt the user for permission to install the updates, and to display suitable messages as it does so.
By the way, the name Software Update Wizard is a bit of a misnomer. This is not a wizard in the sense that VFP developers would understand the term. There is no wizard-style interface in the product.
Our preferred approach to this type of on-the-fly updating is to provide a small loader program to check for updates. It is the loader that the users launch when they execute a shortcut to the application from the desktop or Start menu. After checking for updates, the loader proceeds to launch the main executable - the one that does the actual work of the application.
Of course, this is not the only approach. You might prefer to provide a "check for updates" option in the application itself - via a menu option or a command button, for example. The Software Update Wizard supports this approach. But it is complicated by the fact that, if the executable that launches the Wizard is the one that is being updated, it needs to close down before the new version can be copied over it. The Wizard includes the necessary logic to handle this, but it might still be inconvenient for the user, especially if he or she was working on a difficult or time-consuming task at the time. This issue doesn't arise if you have a separate loader program.
The following is the complete code for a typical loader program. This is an ordinary FoxPro PRG which you would build into an executable in the usual way.
* In these #DEFINES, substitute the URL of your script file, * the timeout for WebUpdateWait(), and the name of the main * executable program. #DEFINE UPDATE_URL "http://www.MyWebSite.com/update.txt" #DEFINE UPDATE_TIMEOUT 2500 #DEFINE MAIN_EXEC "MyExecutable.EXE" LOCAL lcURL, lnTimeout lcURL = UPDATE_URL lnTimeout = UPDATE_TIMEOUT DECLARE INTEGER WebUpdateWait IN wuw4.dll STRING @URL, INTEGER @Timeout * Check for updates and install them if any are found. WebUpdateWait(@lcURL, @lnTimeout) && Note that two parameters are passed by reference * If updates were found, they will now have been installed. * Run the main program. DECLARE INTEGER ShellExecute IN shell32.dll ; INTEGER hndWin, ; STRING cAction, ; STRING cFileName, ; STRING cParams, ; STRING cDir, ; INTEGER nShowWin ShellExecute(0, "open", FULLPATH(MAIN_EXEC), "", "", 1)
The loader also needs an accompanying Config.FPW file. This should have the following minimum commands:
SCREEN = OFF RESOURCE = OFF
You'll probably find it convenient to bind this file into the executable.
As you can see, the loader program calls a function (WebUpdateWait) in the Software Update Wizard's DLL (WUW4.DLL). The first parameter to this function is the URL of a script file on the web server. It is the script file that contains the detailed instructions for the Wizard (more details of this in a moment). The second parameter tells the function how long to wait for a connection before giving up.
As the name of the function suggest, the processing is synchronous. So the loader program will wait for the update to finish before it proceeds to load the main program. The Wizard exposes another function, named WebUpdate, which performs exactly the same job as the one shown here, but does so asynchronously. In our case, we don't want the loader to start launching the main program while an update is in progress, which is why we use the "wait" version.
The script file is an ordinary text file that resides on the web server. The Software Update Wizard has its own scripting language, with over 50 commands and many options and sub-options. Fortunately, you will probably only ever need to know a small subset of these.
Here is a minimum script that will download and install a single file:
The first line is a section number. You need to increment this for each successive version of the script. If the section number is higher than the one that was previously processed for this user, the Wizard will process this new script. In this example, it will download MyExecutable.EXE and copy it over any existing file with that name.
A slightly different approach - and one that we have adopted - is to use the executable's version number to control the processing:
 RunAlways Filename=http://www.MyWebSite.com/MyExecutable.EXE FileVersion=1.9.0
The section number is still present, but only for syntax-checking purposes. What's important here is the FileVersion command. This tells the Wizard to download and install MyExecutable.EXE if, and only if, the user's existing version of that file is less than the one specified in the command (1.9.0 in this example).
For a VFP executable, the version number is the one that you enter in the Version dialogue before you build the application (or which is automatically incremented in that same dialogue). It's the same as the version number that's displayed in the file's Property sheet or that's returned when you call AGETFILEVERSION() in your VFP code.
What if you want to install a type of file that doesn't support built-in version numbers, such as a Help file or an image file? One option would be to use the FileDate command. This works in the same way as FileVersion, except that it uses the file's date stamp as the criterion.
Alternatively, you might take the view that you would only want to install new Help files and the like if you are issuing an updated executable at the same time. If so, you could use a script such as this:
 RunAlways Filename=/MyExecutable.EXE FileVersion=1.9.0 AdditionalFile=http://www.MySite.com/MyHelp.CHM|<CLIENTFOLDER>|<NA>|
Here, the Help file is an "additional" file. You can have as many of these as you like. The Wizard will only download them if the test on the version number or date stamp of the main file (the one specified by Filename) succeeds. Put another way, you're telling the Wizard that, if the users don't need a new executable, they won't need a new Help file either.
The <CLIENTFOLDER> option in the AdditionalFile command is a pointer to the target directory. <NA> is a place-holder for a version number; this doesn't apply in this case, but must still be represented. For no obvious reason, the syntax rules dictate that the AdditionalFile command must always include the full path to the file in question, whereas the Filename command can get away with a relative path (relative to the website's root folder).
What do the users see while all this is going on? By default, they will see a series of progress bars (a separate progress bar for each file being downloaded), and a success message like the one in Figure 1. If the Wizard finds no files to download, nothing will be displayed to the user (which is probably what you want).
To suppress a progress bar, add <noui> to the end of the filename in the Filename or AdditionalFile command. To suppress the default success message, add a NoSuccessMessage command to the script. You can also provide your own success message, by means of the FinalMessage command.
By default, the Wizard downloads the required files without notifying the user or asking their permission. If that's not what you want, add a Message command to the script. You can use this either to advise the user that a download is about to take place, or to ask the user's permission before starting the download. In the latter case, you can optionally allow the user to defer the download to a specified date.
By default, all these messages and dialogues are branded with Power Programmer's logo, colours, etc. You'll probably want to customise them so that they reflect your own branding or style. Various commands are available to achieve that. We won't try to explain them here, but we will show an example of a script that uses some of them:
 RunAlways Filename=/MyExecutable.EXE FileVersion=1.9.0 AdditionalFile=http://www.MySite.com/MyHelp.CHM|<CLIENTFOLDER>|<NA>| NoSuccessMessage FinalMessage=<body scroll="no"><MessageBoxScale=100,80> <p style="font-weight:bold;">Mike's Accounts has been updated.</p> <p>For details of the new features, please see <i>What's New</i> on the Help menu.</p> Icon=<CLIENTFOLDER>\Graphics\Logo.ICO Bitmap=<CLIENTFOLDER>\Graphics\Company.BMP Title=Mike's Accounts<verdana,28> TitleBk=236,238,231,236,238,231 DialogBk=236,238,231 TitleTxt=0,152,48
In this listing, we have wrapped the FinalMessage command over several lines to make it fit the web page. In practice, each command must appear on a single line. Note the HTML tags in this command. You can use tags like these to format the text in almost any way you like. The last three commands all indicate colours or colour pairs, the numbers being RGB codes.
Figure 2 shows the success message which this script will produce.
In general, the Software Update Wizard copes well if things don't go to plan. Importantly, if the web server is down, or if there is no internet connection, the Wizard simply does nothing: it doesn't disturb the user in any way. This is good.
But at other times, things aren't so slick. The Wizard is very fussy about the syntax of the script, and if it doesn't like what it finds, it sometimes displays an intrusive message, like this one:
Syntax error in Update.txt section . 'Filename =/MyExecutable.EXE' is not a valid Software Update Wizard keyword.
This particular message was the result of a spurious space before the equals sign in the Filename command. The message doesn't terminate the program, but it's not something you would want end users to see.
The only way to avoid this situation is to test your scripts very carefully, and to ensure that the person responsible for updating them (who might not be a programmer) fully understands the rules of the scripting language. (Another possibility might be to write a server-side program to generate the scripts dynamically.)
The Wizard has a number of files that you need to install on the end-user's system:
Power Programmer recommends that you install all these files except the licence file in the System32 folder. That way, they can be shared with other applications that use the Wizard. To help with that, the company provides a program called WUWINSTALLER.EXE which handles the installation of these files for you. If you are using an installation package such as InstallShield or Inno Setup, you should tell it to run WUWINSTALLER.EXE after installing the rest of your application (adding /S to the command line will run it silently).
Similarly, instruct the installation package to run WUWUNINST.EXE when you are uninstalling your application.
In theory, you could bypass WUWINSTALLER.EXE and WUWUNINST.EXE, and simply include the distributable files in the installation package itself. You might do this if you want to install them in a sub-directory of the application's executable folder, along with the VFP runtimes and similar components. But before you take that route, you need to be aware of another issue.
This might not be obvious, but the core component of the Software Update Wizard runs as a Windows service. In other words, it is constantly available in the background, waiting for an application to call it to action. Don't worry about this. The overhead, both in terms of memory and CPU usage, is negligible.
The reason for this is simple. By running as a service, the component can operate in the SYSTEM security context. As such, it can perform operations under Windows Vista and Windows 7 that would otherwise be blocked or that would trigger User Access Control (UAC) prompts. These include creating files in folders in the Program Files tree, and writing to certain Registry keys.
If this is not an issue for you, you can opt to run the Wizard as a normal program. But this will become increasingly impractical as more and more users migrate to modern operating systems (and perhaps as the security requirements become more onerous).
This is also one of the reasons that Power Programmer recommends using WUWINSTALLER.EXE and WUWUNINST.EXE respectively to install and uninstall the product. One of the functions of these utilities is to start and stop the Windows service. If you bypassed these utilities and handled the installation and uninstallation manually, you would have to perform that task yourself.
The Software Update Wizard is not the only product available for performing over-the-web updates. Several other vendors offer similar tools. We like the Wizard because it is relatively simple to use, and gives good control over the user interface. If your needs are different, you should shop around for the product that works best for you.
If your users are working on a local network and have access to a shared directory on a server, take a look at Andrew Connor's article, "Installing new copies of VFP executables". In it, Andrew suggests a simple technique for updating the main executable which doesn't require a script files or an internet connection.
You also have the option of writing your own over-the-web updater, which you could do entirely in VFP. This could take the same approach as the Software Update Wizard, using a text file to tell it which files to install from a web server. Alternatively, you could host the updates on an FTP server. In that case, your program could obtain a listing of the server's directory, so you wouldn't need the text file to determine the files that are to be download. If you're not sure how to retrieve files from a web server or FTP server in VFP, consider using West Wind's Internet and Client Tools library for that task.
In this article, we have given a brief overview of Power Programmer's update tool, and shown you how easy it is to incorporate it in a Visual FoxPro application. We've only covered the basic features of the product here. It has a lot more capabilities than those we've discussed.
You can purchase the Wizard direct from Power Programmer. Several licensing options are available, depending on the number of applications you wish to use it with and the level of technical support you need. There is also a free 30-day evaluation version.
To purchase the Software Update Wizard, to download the evaluation version, or to find out more about the product, visit the Power Programmer website.
Mike Lewis Consultants Ltd. August 2011.
FoxStuff is maintained by Mike Lewis Consultants Ltd. as a service to the VFP community. Feel free to download and use any code or components, and to pass around copies of the articles (but please do not remove our copyright notices or disclaimers).
The information given on this site has been carefully checked and is believed to be correct, but no legal liability can be accepted for its use. Do not use code, components or techniques unless you are satisfied that they will work correctly in your applications.
© Copyright Mike Lewis Consultants Ltd.