TCynthesisAppUpdate =================== Date: 02/05/1999 Version: 0.99.0.0 Author: James Waletzky E-Mail: (waletzky@npsnet.com) Company: Cynthesis Software Inc. Web Site: http://www.npsnet.com/waletzky/ Requirements ------------ - Delphi 4.x (apply Update Pack #2 or later) - The TNMHTTP component (provided with Delphi 4.x) must be installed. History ------- Version: 0.99.0.0 - First BETA release. Known Problems (as of Version 0.99.0.0) -------------- - The browse button in the sample application is not working as expected. I have yet to look into this. Again, if you have any ideas, please e-mail me. For now, just type in the path to the DCU file. - If you get a message that there is a new component update available, you cannot change tabs in the test application until you've downloaded the updated. If you don't want the update, simply quit the test app and reload to once again experiement with the sample. - You may need to copy UnzDLL.DLL to the Windows system directory to get things to work properly. Contents -------- - Readme.txt: this file - AppUpdateTest.dpr: sample application project file. - AppUpdateTest.res: resource file for sample application. - AppUpdateTst.dfm: main form file for the test application. - AppUpdateTst.pas: source code for the main form file. - CynthesisAppUpdate.dcu: compiled TCynthesisAppUpdate component. - CynthesisAppUpdate.dcr: component resource file. - CynthesisAppUpdate.int: Interface section for the CynthesisAppUpdate file. - Update.exe: companion helper application that takes care of installing the update. - UnzDLL.dll: helper DLL that handles unzip operations from the update helper application. - AppUpdateTest.ico - icon file for the test application. What is the TCynthesisAppUpdate Component? ------------------------------------------ The TCynthesisAppUpdate component provides the functionality to an application of automatically checking for new versions when on-line, 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 are all that's required for your application to update itself! Other features include: - distribute your binary files in a ZIP file and have the component handle the update; or - distribute your update as an executable (EXE) that is run once the download process has completed. - specify which versions of your application that the udpate is compatible with (you may not want to install a v5.01 update over a v1.0 binary). - the Update helper application will list the files that have been updated (when distributing your update using the ZIP method). - events are fired to your application for all important actions. Limitations of Use ------------------ 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 waletzky@npsnet.com for permission. Cynthesis software has the right to charge a nominal fee for use of this component in a commercial application. The source code for this component is available from Cynthesis Software for a cost of $10 (US Funds). 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. Usage ----- (1) Install the TCynthesisAppUpdate into a package of your choice such that it is available on the component palette. (2) Drop the component on your application's main form. (3) Determine whether you want the component to handle the entire update or you want to do it manually via events (set the UpdateMode property). (4) Fill in the current version of the product. (5) Fill in the URL that will point to the update information INI file. (6) Distribute your application (don't forget to include UPDATE.EXE in your distribution package in the -same directory- as your application executable). (7) When it comes time for an update to your application, create an INI file as described below. (8) Prepare the update information INI file. (9) Upload the INI file and the update file to a web server as indiciated by the UpdateInfoURL property. About the Sample Application ---------------------------- 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, 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. Update Info INI File Format --------------------------- 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= - any string that describes the application (usually just the name of the application). Version= - version number of the update; usually in the following format: w.x.y.z InstallAction= - see the InstallAction property on the component for details. UpdateURL= - URL to the zip or executable file that represents the update. Details= - any text used to describe the update; could be an abbreviated list of changes. CompatibleVersions=,,... - 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. Creating the Update ZIP File ---------------------------- 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. Component Properties -------------------- PUBLISHED (Design-time/Run-time): 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/AppUpdate.ini UpdateMode - TCynthesisAppUpdateModes - If set to mAutoWithUI, the TCynthesisAppUpdate component will handle the entire update process using its own UI and dialog boxes. This includes checking for the update, prompting the user to install it, and installing it - all without intervention from your application. If set to mAutoNoUI, the same events will occur except no UI will appear. The update will occur without user intervention. If set to mManual, you have to display the update UI by handling the various events that are thrown from the component. CurrentVersion - string - The version of your application that you are currently releasing. This version is checked against the one listed in the update info INI file to determine if an update is required. PUBLIC (Run-time): DestDirectory - Run-time only (read/write) - string - Optional parameter 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 - TCynthesisAppUpdateInstallActions - run-time only (read/write) - The various values are as follows: iaNone: Don't do anything when told to install the application iaUseUpdate: Use the update helper application when told to install the application. This implies that the update file on the web server is a ZIP file and the helper application will unzip it to the same destination directory as your application resides in keeping subdirectories intact. iaRunExecutable: The update to be downloaded is an executable file. Instead of using the helper application to install the update, simply run the downloaded executable. Component Methods ----------------- Initialize; - Make sure that this method is called before using the component within an application. CheckForUpdate: TCynthesisAppUpdateError; - Call this method to check the web server for an update. 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 in the future if there is a demand. 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. - 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 AppUpdateTypes.pas Component Events ---------------- 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. 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. 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. 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. OnError(Sender: TObject; ErrorInfo: TCynthesisAppUpdateError) - 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 OnUpdateAborted(Sender: TObject; eReason: TUpdateAbortReasons) - This event is fired when the update process has been aborted for some reason. Updates can be aborted because of an error in download, or perhaps because the user cancelled the update. This event handler presents a good way to restore the initial state of your application before the update process was started. Note that when a fatal error occurs in the update process, the AppUpdate component will fire the error event, as well as this event. - See AppUpdateTypes.pas for details on the TUpdateAbortReasons type. Tips and Tricks --------------- Here are some tips and tricks to help you out when using the component: - Check out the sample application called AppUpdateTest - it will give you a good idea as to how the component works and what to do in the case of a manual update. - The TCynthesisAppUpdate component will close your application automatically once the InstallUpdate method is invoked. This is to ensure that none of the application files are in use when the update is applied. Your application should be coded to expect this situation. - Use the iaUseUpdate install action when you simply want to update certain files that have been installed to some file hierarchy in or under where your application's executable file is located. If you need to apply new registry settings, or install files to a different directory (e.g. under the Windows system directory), it is recommended that you write a small install program (e.g. using InstallShield) that does not permit any user interaction, but simply installs the files to the appropriate locations and adjusts the registry, etc. as required. - It is recommended that every time you distribute an update for your application you update the main executable whether it needs it or not. This has the effect of updating the version number used by the update component to determine if an update on the web is newer than the one currently installed. Acknowledgements ---------------- Special thanks to Eric W. Engler for creating the Delphi Zip/Unzip component that this component leverages.