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=<string>
  - any string that describes the application (usually just the name of the
    application).

Version=<string>
  - version number of the update; usually in the following format: w.x.y.z

InstallAction=<None|UseUpdate|RunExecutable>
  - see the InstallAction property on the component for details.

UpdateURL=<string>
  - URL to the zip or executable file that represents the update.

Details=<string>
  - any text used to describe the update; could be an abbreviated list of
    changes.

CompatibleVersions=<string>,<string>,...
  - 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.