The TCynthesisAppUpdate component provides an application with the capability of automatically checking the web for updates to your application, and automatically downloading and installing the update if one is found. This page provides more detail on the component.
Download TCynthesisAppUpdate Now! (430K ZIP File)
Download ZipMaster
Now! (500K ZIP File; used by the
TCynthesisAppUpdate component)
Note: I have made some small changes to
the ZipMstr.pas file - you should use the one that comes with the AppUpdate
component, or make the equivalent changes in the ZipMstr.pas source in the ZIP
file above.
Date: | 12/1/1999 |
Version: | 2.1.0.0 |
Author: | James Waletzky |
E-Mail: |
Coming real soon: Delphi 5 support!
Version: | Notes: |
2.1.0.0 |
|
2.0.0.0 |
|
1.0.0.0 |
|
0.99.0.0 |
|
The TCynthesisAppUpdate component provides the functionality to an application of automatically checking for new versions when on-line (via a HTTP web connection, FTP connection, or network connection), and downloading and installing application updates. The component can handle the entire update process using its own user interface, or you can capture a few simple events and handle the update process manually. Dropping the component on your application's main form, setting some properties, creating a simple INI file, and placing both the INI file and the zipped update on a web server, FTP server, or network drive are all that's required for your application to update itself!
Other features include:
The TCynthesisAppUpdate component (and its various pieces) is free for non-commercial use . All I ask is that you send me an e-mail telling me that you are using the component. For use in a commercial application , please contact me (James Waletzky) via e-mail at cynthesis@home.com for licensing details. Cynthesis software has the right to charge a fee for use of this component in a commercial application. Please contact me for commercial licensing and I will forward the license agreement to you via e-mail.
The source code for this component is available from Cynthesis Software for a suggested cost of $10 (US Funds). Higher denominations are encouraged, however, to fund future development. The source code may be modified for your use but may not be redistributed. You may include the source code in any non-commercial applications that you develop without royalty. To purchase the source code please remit a cheque or money order payable to Cynthesis Software Inc. to the following address:
Cynthesis Software Inc.
408 - 260 Newport Drive
Port Moody, BC
Canada
V3H 5C6
If you decide to make use of this component, I would like to hear from you as to your comments about the component, or suggestions for improvement.
The sample application illustrates how to use the TCynthesisAppUpdate component in a couple of different ways. It consists of two tabs - one that allows you to update the sample application itself using one of the specified protocols, and another tab to update this component package. The first tab takes a modal dialog approach and informs the user when the update is available, asks to download, etc. via dialog boxes. The second tab updates the component package via a changing button state (run it to see what I mean). When an update is available you will be presented with an edit box where you fill in the path where your component files reside. The update will unzip the new version over top. For full details on how this works, check out the source. I have tried to comment it fairly thoroughly.
Note: The sample application has not been translated to languages other than English. Therefore, if you set the ResourceDLL property on any of the AppUpdate components on the sample form, some messages will remain in English.
The Update Info INI File describes the most recent application update that is sitting on the web server. The TCynthesisAppUpdate component first downloads this INI file to determine whether an update is necessary before downloading the update itself. You will need to create an INI file and upload it to the location specified in the UpdateInfoURL property of the component every time an update is available.
The format of the INI file is as follows (anything that appears in angle brackets <> should be replaced):
[UpdateInfo]
Name | Value | ||||||
---|---|---|---|---|---|---|---|
Name |
|||||||
Version |
[string] version number of the update; usually in the following format: w.x.y.z | ||||||
InstallAction |
[enumeration] see the InstallAction property on the component for details. | ||||||
UpdateURL |
[string] Location of the zip or executable file that represents the update.
Note: all lowercase is recommended for this value as well as the actual name of the file and directories on the server when OnlineMode is olFTP to avoid case sensitivity issues. | ||||||
Details |
|
SmartCompare
| [boolean]Indicates the type of comparison that is performed when comparing version information.
SmartCompare is especially useful when the component's CurrentVersion property is left blank to cause CurrentVersion to be extracted from the exe's embedded version number. Examples: With SmartCompare True:
With SmartCompare False:
Regardless of SmartCompare setting:
|
CaseSensitiveCompare [boolean] The default value is False, no case sensitivity in version
comparison. Applies to comparison of CompatibleVersions and Version INI
variables with component property CurrentVersion. | CompatibleVersions |
| [string; comma-delimited] A list of versions (in the same format as the version field) that this update can be applied over top of. If the user has, say, version 1.0.0.0 of your application installed, the patch may not apply. You may only want to patch 2.0.0.0 clients. Any person with a 1.0.0.0 client will have to upgrade to 2.0.0.0 before applying the update. If the SmartCompare INI variable is True, then you can use "wildcards" here. For example, CompatibleVersions=1.9.*,2.* would update all versions begining with '1.9.' or '2.'. Note that the '*' must be the only character of the segment in order to be considered a wildcard, and if it's not the last segment, then and trailing segments will be ignored. There is no wild card in '2.2*.3' or '2.*2.3'. Also, '2.*' is the same as '2.*.1'. This INI variable is optional. If missing, it is assumed that any version is compatible with the update, if its version compares older than the update. |
When using the install action iaUseUpdate, you need to create a ZIP file containing the update and place that file on a web server for retrieval. This file should take on the same directory structure as your application. For example, if your directory structure looks like this:
MyApp (where your main executable is stored)
+ Samples
+ Help
+ Doc
then your update ZIP file should have the same structure so that you can place updated files directly over top of the currently installed versions. You may want to place a CHANGES.TXT file inside your update so that the user can view the release notes for the update some time after the update has been applied.
The AppUpdate component is easily localized to different languages. By default, the component has English messages linked into the component. If a different language is desired, the following actions must be performed:
Shortcut: A shortcut to the above procedure would be to copy one of the sample resource DLLs included with the AppUpdate component (e.g. AppUpdateDE.DLL) to a new file. Open the DLL in a resource editor and replace the resources in the DLL with your own translations.
Note: This technique of localization even allows you to change languages dynamically at run-time simply by shipping the appropriate resource DLLs with your application and setting the ResourceFilename property on the component.
Note: Unfortunately, the strings that are defined within the HTTP component and FTP component that are used by the AppUpdate component are not localized. Therefore, some rarely seen error messages may in fact appear in English even though you have localized the component for a different language. I will do my best to find a better, cross-language, HTTP and FTP helper component in the near future.
Property | Type | Description |
---|---|---|
CurrentVersion |
string |
The version of your application that is currently running. If this property is left blank, the component will attempt to extract the version number from the current running EXE file (which you supply in the Project/Options/Version Info tab, or is maintained by your version control system). An error is raised if version information cannot be found. This version number is compared to the one listed in the update info INI file. If this version is older, (and if it is in the CompatibleVersions list, when this list is supplied) then the update process continues. |
ResourceDLL |
string |
By default, the english-language strings associated with the component are linked into your application. If strings have been translated to another language and are present within some external DLL, this property should contain the filename (no path information) of the DLL that contains the string resources. The resource DLL file should be distributed in the same directory as your application executable. See Localizing Message Strings for details. |
OnlineMode |
TCynthesisAppUpdate-OnlineModes |
The value of this property affects the formatting requirements of the UpdateInfoURL property and of the INI file variable UpdateURL. |
UpdateInfoURL |
string |
The URL that points to the update info INI file that you will create when an update is available e.g. http://www.npsnet.com/waletzky/samples/SampleAppUpdate.ini |
ProxyServer |
string |
Name or IP address of the proxy server if the running application needs to access the target URL or FTP server via a proxy server. Note that if the user's ISP requires a proxy server specification and OnlineMode is olHTTP, there could be a problem with the running exe not "seeing" the most current INI file because of the proxy server only updating its contents occasionally (cache is out of sync). This could create the situation where you program an "instant fix", you put up a new version, call the user and say "it's there, download it", but the user's CheckForUpdate routine downloads the previous INI file from the proxy server, since the proxy server has not updated itself yet. If instant updates are a reality for you, FTP is recommended. This property is ignored when OnlineMode is olLANWAN. |
ProxyPort |
integer |
Number of the proxy port on the proxy server. This MUST be > 0 if the proxy server string is non-blank. This property is ignored when OnlineMode is olLANWAN |
UserName |
string |
Must be non-blank when OnlineMode olFTP and will be used by the FTP hosts specified both in the UpdateInfoURL property and in the UpdateURL INI variable. Logging into a public directory of a public FTP server usually requires the User ID "anonymous", whereas logging into a private directory of any FTP server will require a directory-specific User ID. Normally FTP user names are case sensitive. UserName will also be used when non-blank and OnlineMode is olLANWAN and a UNC specification is given in the UpdateInfoURL property or in the UpdateURL INI variable, when making the connection to the //machine/sharename specified. In this case, UserPassword (see below) may or may not also be required. |
UserPassword |
string |
Must be non-blank when OnlineMode olFTP and is used by the FTP hosts specified both in the UpdateInfoURL property and in the UpdateURL INI variable. In case of a public FTP server where "anonymous" is used for the UserName, the usual practice is to supply the user's email address for the password. An option that usually works with "anonymous" in the case where you need to hardcode a password is to use "guest@unknown" or "-". Normally FTP passwords are case sensitive. UserPassword will also be used when non-blank and OnlineMode is olLANWAN and a UNC specification is given in the UpdateInfoURL property or in the UpdateURL INI variable, when making the connection to the //machine/sharename specified. In this case, UserName (see above) may or may not also be required. |
UpdateMode |
TCynthesisAppUpdate-Modes |
|
Property | Usage | Type | Description |
---|---|---|---|
DestDirectory |
Run-time only (read/write) |
string |
Optionally set to indicate where the files in the update ZIP file should be unzipped to. If this property is left blank, the destination directory is the same directory in which your application executable resides. |
UpdateFilename |
Run-time only (read) |
string |
The name of the update ZIP file that was downloaded from the web server. |
InstallAction |
Run-time only (read/write) |
TCynthesisAppUpdate-InstallActions |
The various values are as follows:
|
FileSize |
Run-time only (read) |
LongInt |
The size of the file being downloaded during CheckForUpdate or DownloadUpdate. If value is zero, the filesize has not been calculated yet. (Could be used to abort if deemed by event handler to be too big for downloading, etc.) |
Method Signature | Description |
---|---|
Initialize; | Make sure that this method is called before using the component within an application. If you want to override any design-time values you assigned to the component properties, assign the override values prior to calling this method. For example, your application may prompt the user for UserName, UserPassword, ProxyServer, and ProxyPort. |
CheckForUpdate: TCynthesisAppUpdateError; |
Call this method to check the web, FTP, or LAN/WAN server for an update. Note that for mode umAutoWithUI and umAutoNoUI, you call only Initialize and then this method. A good place to call this method is when your application is initializing. Another possible spot is when the user chooses a menu item in your application like "Check For Updates". Note that if you call CheckForUpdate and you are not on-line, the standard Windows dial-up networking dialog box will appear asking you to dial in to your Internet service provider. You may want to have your application check the on-line status and only call CheckForUpdate if you are on-line. If there is demand for this feature, I may add the check to the component itself. |
DownloadUpdate: TCynthesisAppUpdateError; |
Call this method once it has been determined that an update is available and the user has decided to apply it. This method should be called from the OnUpdateAvailable event handler in the case of a manual update. Note that the "auto" UpdateModes will call this method for you. |
InstallUpdate: TCynthesisAppUpdateError; |
Call this method once the update file has been successfully downloaded and the user wishes to apply the update. This method should be called from the OnDownloadComplete event handler in the case of a manual update. Calling InstallUpdate will trigger the update of the UPDATE.EXE helper application and resource DLL (if one is being used). The update of these files are necessary at this point as updating the helper application while it is running is not possible due to the files being loaded in memory. Note that the "auto" UpdateModes will call this method for you. |
CancelUpdate: TCynthesisAppUpdateError; | Call this if for some reason you want to abort the update process once it has been started. |
* For a definition of the TCynthesisAppUpdateError structure, see the file CynthesisAppUpdateTypes.pas
Event Signature | Description |
---|---|
OnUpdateAvailable( Sender: TObject; Version: String) |
This event is fired by the update component when an update has been found. The Version string indicates the version of the update that was found on the web server. This event allows the application to prompt the user to download the update, or dismiss the update until some later time. You should call DownloadUpdate once it is determined that the update should be downloaded. If you are using umAutoWithUI mode and you do not furnish this event handler, the component will automatically prompt to download the update or cancel. |
OnNoUpdateAvailable( Sender: TObject) |
This event is fired when it is determined that no update exists on the web server. This may be because either an update info file does not exist, or because the version on the web server is the same or earlier than the one currently installed. This type of event is required since the whole update checking sequence is asynchronous. If it was synchronous, you could simply wait for a result code from the CheckForUpdate method. If you are using umAutoWithUI mode and have not supplied this event handler and no update is available, a messagebox 'No Update Available' will be presented to the user. |
OnDownloadProgress( Sender: TObject; Progress: Integer; Msg: String) |
This event is fired by the update component periodically to indicate the current progress and status of the update file download. The Progress parameter indicates a percentage complete, and the message is a status string that you may want to display in a status bar. This is a good place to update a progress bar based on the value, and display the message on a status bar. If you are using umAutoWithUI mode and have not supplied this event, the component will present a progress window with progress text and a progress bar for both downloads (info file and update). |
OnDownloadComplete( Sender: TObject) |
Called when the download of the update is complete. This is a good spot to warn the user that the application will now be closed and that the update will now be applied. You should call InstallUpdate once it is determined that the update is to be applied. |
OnUpdateAborted(Sender: TObject; eReason: TUpdateAbortReasons) |
This event is called when an error occurs when attempting to download the update or the update file. The error message will indicate the problem so you should display it to the user.. If you are using umAutoWithUI mode and have not suppied this event handler, the component will suppy its own and present appropriate error messages. |
OnError( |
This event is called when an error occurs when attempting to download the update or the update file. The error message will indicate the problem so you should display it to the user. - See AppUpdateTypes.pas for details on the TCynthesisAppUpdateError s structure |
Here are some tips and tricks to help you out when using the component: