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.
Please: If you have any problems with the component whatsoever, from installation to potential bugs, please get in touch with me via e-mail . That's the only way I can improve the component!
Download TCynthesisAppUpdate for Delphi 5 now! (540K
ZIP File)
Download
TCynthesisAppUpdate for Delphi 4 now! (540K 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.
Download the Internet Component Suite Now! (970K ZIP File; used by the TCynthesisAppUpdate component)
Date: | 8/10/2000 |
Version: | 3.0.0.0 |
Author: | James Waletzky |
E-Mail: |
Version: |
Notes: |
---|---|
3.0.0.0 |
|
2.2.0.0 |
|
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:
If you have any great ideas for features in this component (or additional components), please be sure and let me know !
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.
Note: A commercial
application is an application that you have developed from which
revenue is derived, such as sales, license fees, development contract fees,
advertising, etc.). A non-commercial application (or freeware) is an
application you have developed from which no revenue is derived, and is
provided to the public domain without usage restrictions.
The source code for this component is available by donation 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.
IMPORTANT: Telephone support will not be provided for this component. All correspondence must occur via e-mail.
The component, as distributed without source code, works best if you configure your applications to use the TCynthesisAppUpdateD?.BPL, ZipMasterD?.BPL and ICSDEL?0.BPL files as run-time packages (late binding). You can set this property in your project settings on the Packages tab by selecting the "Build with runtime packages" checkbox and ensuring that the edit box contains entries for TCynthesisAppUpdateD?, ZipMasterD?, and ICSDEL?0.
To statically link in the AppUpdate, ZipMaster and ICS components into your application (early binding), you should ensure that "Build with runtime packages" is left unchecked (or the AppUpdate, ZipMaster and ICS packages are removed from the edit box) and add the paths to your AppUpdate, ZipMaster and ICS DCU files to the "Search Path" entry on the "Directories/Conditionals" tab in the project options. This will cause Delphi to link in the DCU files instead of use the packages at run-time. This works in my test configuration, but the odd person has had trouble getting their application to build. If you can't seem to work through the problems, I recommend purchasing the source code, as that will alleviate all problems.
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, provides full information about the update, asks the user 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.
Note: Make sure that the path to the ICS source code (<path>\ICS\Delphi\VC32) is listed in the search path of the sample application project options.
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 |
[string] see the InstallAction property on the component for details. The actual strings that should be present in the INI file that map to the InstallAction enumerations are (leave out the quotes when inserting these strings into the INI file):
| ||||||
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. | ||||||
ReadmeURL |
[string; optional] URL to a README file that describes the update. The README file is a good place to place detailed and formatted release notes about the update so that the user may make an informed decision as to whether the update should be downloaded and installed. | ||||||
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; optional] 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 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. |
OnlineMode |
TCynthesisAppUpdate-OnlineModes |
The value of this property affects the formatting requirements of the UpdateInfoURL property and of the INI file variable UpdateURL. |
Port |
integer |
Number of the port used by the HTTP client or FTP client to connect to the server to download the update. This property is ignored when OnlineMode is olLANWAN |
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 can be set to 0 to use the default port. This property is ignored when OnlineMode is olLANWAN Note: This property is not used with the OnlineMode olFTP due to the ICS FTP Component not supporting proxy port as a property. In the future when this property is added, AppUpdate will be adjusted accordingly. |
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. |
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 |
UpdateMode |
TCynthesisAppUpdate-Modes |
|
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. |
Property | Usage | Type | Description |
---|---|---|---|
DestDirectory |
Run-time (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 (read) |
string |
The name of the update ZIP file that was downloaded from the web server. |
InstallAction |
Run-time (read/write) |
TCynthesisAppUpdate-InstallActions |
The various values are as follows:
|
FileSize |
Run-time (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; versionInfo: TCynthesisAppUpdateVersionInfo) |
This event is fired by the update component when an
update has been found. The versionInfo object provides detailed
information about 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 |
The OnUpdateAvailable event is an important part of the TCynthesisAppUpdate component. This event is triggered in your code every time an update is discovered on the update server. The versionInfo object that is supplied as part of the event provides detailed information about the update. This information may be displayed in a dialog, on your form, or whatever you desire.
The update information that is available is described in the table below. Note that all of these values are pulled out of the update information file (INI) that is retrieved from the server during the update discovery stage (the call to CheckForUpdate).
Property | Description |
---|---|
Name |
Specifies the name of the update (usually the same as the application being updated) |
CurrentVersion |
The current version of the application to be updated (taken from the application's version resource). |
NewVersion |
The version of the update that is available on the server. The new version is always greater than the old version. |
Details |
The details about the update (can be any string) |
Company |
The name of the company supplying the update. |
UpdateSize |
The size of the update (not currently implemented) |
UpdateURL |
The URL that will be used to download the update. |
ReadmeURL |
A URL to a readme file. This file may be of any type (HTML, Word document, text file, etc.). It is recommended that you simply pass the ReadmeURL property to the ShellExecute function for display to the user. This will have the effect of popping up the user's default web browser with the document loaded instead of it. |
Here are some tips and tricks to help you out when using the component: