This section describes the install script.
Creating an Install Script
You will usually want some form of control over your install process. For example, you may wish to check versions of files and only install updated files, or perhaps you wish to apply patches to existing files. The install script is even flexible enough to allow you to uninstall files. For this reason, installers include an install script to handle the installation process.
In an HTML document, or a XUL document, the window object is the root global object. That means that you can call the methods of the window object with the qualifier before it, which means that window.open(...) can simply be written open(...). In an install script, there is no associated window, however the global object will be an Install object which contains a number of functions to customize the install process. Some of the Install object's functions will be described below.
The install script should take the following steps:
- Initialize the installation by specifying what package and version is being installed.
- Use the Install functions to indicate what files and directories need to be installed. You can also set files to be moved and deleted.
- Start the process of installing the necessary files.
It is important to note that during step two, you only indicate which files should be installed and any other operations you wish to have happen. No files get copied until step three. Because of this, you can easily specify a number of files to be installed, come across some kind of error, and abort the whole process without modifying the user's system.
The Component Registry
Mozilla maintains a file which is a registry of all the components that are currently installed. Components include new chrome packages, skins and plugins. When a new component is installed, the registry gets updated. The registry also stores the set of files and version information about the installed components. That way, it is easier to check if a version of your component is already present and only update it if necessary.
The component registry works somewhat like the Windows registry does. It consists of a hierarchy of keys and values. You don't need to know much about it to create XUL applications unless you are creating your own XPCOM components.
What you do need to know for an installation is that the registry stores a set of information about your application, such as the file list and versions. All of this information is stored in a key (and within subkeys) that you provide in the installation script (in step 1 mentioned above).
This key is structured as directory-like path of the following form:
Replace the word Author with your name and replace the Package Name with the name of the package that you are installing. For example:
/Xulplanet/Find Files /Netscape/Personal Security Manager
The first example is what we'll use for the find files dialog. The second is the key used for the Personal Security Manager.
The Install object has a function, initInstall which can be used to initialize for the installation. It should be called at the beginning of your installation script. The syntax of this function is as follows:
initInstall( packageName , regPackage , version ); Example: initInstall("Find Files","/Xulplanet/Find Files","0.5.0.0");
The first argument is the name of the package in user-readable form. The second argument is the registry key used to hold the package information as described earlier. The third argument is the version of the package being installed.
Next, we need to set the directory where the files will be installed. There are two ways to do this. The simple method assigns an install directory and installs all files into it. The second method allows you to assign a destination on a per-file (or directory) basis. The first method is described below.
The function setPackageFolder assigns an installation directory. For the find files dialog, we will install the files into the chrome directory. (We could actually put them anywhere though.) The setPackageFolder takes one argument, the directory to install to. For maximum portability, you can't specify a string name for the directory. Instead, you specify an identifier of a known directory and get subdirectories of it. Thus, if your application needed to install some system libraries, you don't need to know the name of those directories.
The directory identifiers are listed in the reference. For the chrome directory, the directory identifier is 'Chrome'. The getFolder function can be used to get one of these special directories. This function takes two arguments, the first is the identifier and the second is a subdirectory. For example:
findDir = getFolder("Chrome","findfile"); setPackageFolder(findDir);
Here, we get findfile folder in the Chrome folder and pass it directly to the setPackageFolder function. The second argument to getFolder is the subdirectory which we are going to install into, which doesn't have to exist. You can leave this argument out entirely if you don't need one.
Setting Install Files
Next, you need to specify which files should be installed. This involves the use of two functions, addDirectory and addFile. The addDirectory function tells the installer that a directory from the XPI archive (and all of its contents) should be installed to a particular location. The addFile is similar but for a single file.
Both the addDirectory and addFile functions have various forms. The simplest takes only one argument, the directory from the installer to install to the assigned installation directory.
addDirectory ( dir ); addFile ( dir ); Example: addDirectory("findfile");
The example above will specify that the findfile directory from the installer archive should be installed. We can call these functions multiple times to install other files.
Next, we'll want to register the find files in the chrome system so that it can be used with a chrome URL. This can be done with the registerChrome function. It takes two arguments, the first is the type of chrome to register (content, skin or locale). The second is the directory containing the contents.rdf file to register. Because the find files dialog contains content, a skin file and a locale file, registerChrome will need to be called three times.
registerChrome(Install.CONTENT | Install.DELAYED_CHROME, getFolder(findDir, "content")); registerChrome(Install.SKIN | Install.DELAYED_CHROME, getFolder(findDir, "skin")); registerChrome(Install.LOCALE | Install.DELAYED_CHROME, getFolder(findDir, "locale"));
The DELAYED_CHROME flag is used to indicate that the chrome should be installed the next time Mozilla is run.
The addDirectory and addFile functions don't copy any files. They only state which files should be installed. Similarly, registerChrome only states that chrome should be registered. To complete the process and begin copying files, call the performInstall function. It takes no arguments.
The final script for installing the find files component is shown below:
initInstall("Find Files","/Xulplanet/Find Files","0.5.0.0"); findDir = getFolder("Chrome","findfile"); setPackageFolder(findDir); addDirectory("findfile"); registerChrome(Install.CONTENT | Install.DELAYED_CHROME, getFolder(findDir, "content")); registerChrome(Install.SKIN | Install.DELAYED_CHROME, getFolder(findDir, "skin")); registerChrome(Install.LOCALE | Install.DELAYED_CHROME, getFolder(findDir, "locale")); performInstall();
(Next) Next, we'll look at some additional install functions.