• Skip to main content
  • Select language
  • Skip to search
MDN Web Docs
  • Technologies
    • HTML
    • CSS
    • JavaScript
    • Graphics
    • HTTP
    • APIs / DOM
    • WebExtensions
    • MathML
  • References & Guides
    • Learn web development
    • Tutorials
    • References
    • Developer Guides
    • Accessibility
    • Game development
    • ...more docs
Archive of obsolete content
  1. MDN
  2. Archive of obsolete content
  3. Archived Mozilla and build documentation
  4. XPInstall
  5. Learn XPI Installer Scripting by Example

Learn XPI Installer Scripting by Example

In This Article
  1. About browser.xpi
  2. Overview of the Install Script
    1. Initializing the Installation
    2. Verifying the Target
    3. Adding Files and Directories (Full of Files) to the Install
    4. Registering the Software
    5. Executing the Installation
  3. Installation Logging
  4. Extending the Example
  5. Original Document Information

Parts of this page show the use of the XPInstall API. The majority of this API is now deprecated and as of Gecko 1.9 no longer available. Extension, Theme, and plug-in developers must switch away from install.js based packages to the new packaging scheme with an install.rdf manifest. In particular plugin developers should see how to package a plugin as an extension.

This article uses the installer script from browser.xpi install package as the basis for discussing XPI installations in general. This installer script is relatively short, but it exercises most of the important features of the XPInstall API, and it can easily be used as a template for other more general software installations. In this article, we use the unix install file, but the installers for all the platforms are quite similar, and you can easily take what you learn here and apply it to installations on any platform that mozilla supports.

About browser.xpi

browser.xpi is the XPI archive in which the main components of the Mozilla browser are archived for installation. Mozilla cross-platform installations use the XPI format as a way to organize, compress, and automate software installations and software updates. A XPI is a PKZIP-compressed archive (like ZIP and JAR files) with a special script at the highest level that manages the installation. That installer script , usually named install.js, is the subject of this article.

First, a quick scan of the contents of the XPI file (which you can open using with any unzip utility) reveals the following high-level directory structure:

install.js
bin\
  chrome\
  components
  defaults\
  icons\
  plugins\
  res\

Note that this high-level structure parallels the directory structure of the installed browser very closely:

mozilla directory on linux

As you will see in the installation script, the contents of the archive are installed onto the file system in much the same way that they are stored in the archive itself, though it's possible to rearrange things arbitrarily upon installation--to create new directories, to install files in system folders and other areas.

Overview of the Install Script

XPI install scripts are written in JavaScript using XPInstall Engine syntax defined in the XPInstall API Reference.

Most installation scripts, including the one discussed here, take the following basic form (in pseudo-code and with links to the sections in which these installation steps are documented):

initInstall();
if (verify_space()) {
   err = add_dirs_and_files;
   register_files;
   if (err==SUCCESS) { performInstall() };
   else { cancelInstall() };
}

As you can see in the code listing, the verification process at the top is on lines 1 to 18; the file addition process, here part of the main installation block, is on lines 24 to 41; the registration part of the main installation block is on lines 42-58; and the execution at the end of the main block is on lines 59 to 71. If you choose not to register the installed software or do the verifications at the front end of the installation, then at a minimum, the install scripts must initialize, add the files to be installed, and execute.

Note also that when you call methods on the Install--as you do so often in installation scripts (getFolder, initInstall, addFile, and performInstall are all examples of common Install object methods)--the Install object is implicit; like the window object in regular web page scripts, the Install object does not need to be prefixed to the method.

Initializing the Installation

All installations must begin with initInstall(). The initInstall() method on the Install object creates a new installation for the specified software and version. In the browser.xpi installation, this function appears at line 20: var err = initInstall("Netscape Seamonkey", "Browser", "6.0.0.2000110807");

If you call a method on the Install object before initInstall(), you will get an error.

The initInstall method takes the following parameters: the display name of the package, the name of the package as it appears in the client registry, and the version, which can be expressed as a number or as an InstallVersion object. In the example above, "Netscape Seamonkey" is the display name, "Browser" is the registry name, and the version is "6.0.0.2000110807." See initInstall in the XPInstall API Reference for more information on the initialization process.

Verifying the Target

The first thing the installation script does when it's executed is to check that there is adequate disk space for the software to be installed, where the verifyDiskSpace function is called as a condition of the main installation block that starts at line 24).

 // this function verifies disk space in kilobytes
 function verifyDiskSpace(dirPath, spaceRequired)
 {
   var spaceAvailable;
   // Get the available disk space on the given path
   spaceAvailable = fileGetDiskSpaceAvailable(dirPath);
   // Convert the available disk space into kilobytes
   spaceAvailable = parseInt(spaceAvailable / 1024);
   // do the verification
   if(spaceAvailable < spaceRequired)
   {
      logComment("Insufficient disk space: " + dirPath);
      logComment("  required : " + spaceRequired + " K");
      logComment("  available: " + spaceAvailable + " K");
      return(false);
   }
   return(true);
 }

In the verifyDiskSpace block, fileGetDiskSpaceAvailable is called with dirPath as its expected input. This input is defined in line 22, where getFolder() is used to assign a value to the communicatorFolder variable representing the "Program" folder on the local system:

var communicatorFolder = getFolder("Program");
spaceAvailable = fileGetDiskSpaceAvailable(dirPath);

spaceRequired, the other expected input to the verifyDiskSpace function, is given as 17311 kilobytes on line 19. Inside the function, the two sizes are compared and if the available space is larger than the required space, the installation proceeds.

Adding Files and Directories (Full of Files) to the Install

Once you have verified that the target can accomodate the software to be installed and initialized the actual installation, you must add files and directories to the installation in order to have them installed. In the browser.xpi install script, the files are added in lines 26-41:

  err = addDirectory("Program",
                     "6.0.0.2000110807",
                     "bin",              // jar source folder
                     communicatorFolder, // target folder
                     "",                 // target subdir 
                     true );             // force flag 
  logComment("addDirectory() returned: " + err);
  // create the plugins folder next to mozilla 
  var pluginsFolder = getFolder("Plugins");
  if (!fileExists(pluginsFolder))
  {
      var ignoreErr = dirCreate(pluginsFolder);
      logComment("dirCreate() returned: " + ignoreErr);
  }
  else
      logComment("Plugins folder already exists");

In this case, the files are contained within a single directory, so calling the Install object's addDirectory method is sufficient to queue all the files in the archive for installation. The addDirectory, like addFile, handles both the source file location and the target location. In the example above, all of the contents of the "bin" directory in the archive are queued for installation, and the target of that installation (when the installation is actually begun with a call to performInstall at the end), is the communicatorFolder directory defined at line 22 as "Program."

"Program" is one of a short list of keywords that can be used in place of full path names in methods such as addFile. "Program" represents the directory where software itself is installed (e.g., C:\Program Files\ on win32 systems), as opposed to supporting directories like "Components", "Chrome", or "Temporary" (see getFolder in the XPInstall API Reference for a list of keywords).

Registering the Software

Registering software is sometimes a requirement of both the operating system and of the Netscape 6 platform. When you install new chrome, for example, like the browser.xpi install does, you need to alert the chrome registry to these changes, so that skins, user preferences, packaging lists, and localization bundles will all track the new software.

For registering software with the win32 operating system, the XPInstall API provides two special Install objects, WinProfile and WinReg. These two objects provide programmatic access to the Windows user profile and the Windows registry, respectively. The browser.xpi install script does not demonstrate the use of these objects, but see the XPInstall API Reference for more information about registering software with the win32 operating systems and other operating systems.

To register new Netscape 6-based software (e.g., plug-ins, new components, new themes, new packages) with the chrome registry, you must use the registerChrome function of the Install object. If successful, this function returns a "0" and makes entries into the installed-chrome.txt file in the chrome subdirectory, which is then used to regenerate the various RDF files that make up the chrome registry.

 var cf = getFolder("Chrome");
 registerChrome(CONTENT | DELAYED_CHROME, getFolder(cf,"toolkit.xpi"),"content/global/");
 registerChrome(CONTENT | DELAYED_CHROME, getFolder(cf,"browser.xpi"),"content/communicator/");
 registerChrome(CONTENT | DELAYED_CHROME, getFolder(cf,"browser.xpi"),"content/editor/");
 registerChrome(CONTENT | DELAYED_CHROME, getFolder(cf,"browser.xpi"),"content/navigator/");
 registerChrome(SKIN | DELAYED_CHROME, getFolder(cf,"modern.jar"),"skin/modern/communicator/");
 registerChrome(SKIN | DELAYED_CHROME, getFolder(cf,"modern.jar"),"skin/modern/editor/");
 ...

In lines 42-58, registerChrome is called as many times as there are different directories that contain content that needs to be registered with the chrome registry. Note that in the first few lines of this process, new content from the XPI is being registered, and in the remainder, it is new skin information. In this most common form of the registerChrome function (it can also be used to support the now-deprecated manifest.rdf style of installation archive), the three parameters represent, in order, the chrome SWITCH used to indicate what kind of software is being registered, the target destination of the software (e.g., the "Chrome" folder in the example above), and the path within the XPI (or JAR theme archive) where the contents.rdf file is located.

See registerChrome in the XPInstall API Reference for more information about registering new packages with the chrome registry.

Executing the Installation

Once you have added all the files to the installation, the final step is to actually execute the installation. Note that until this point, the install calls you have been making on the Install object are preliminary only. Recall that an install process takes the following general form:

initInstall();
if (verify_space()) {
   err = add_dirs_and_files;
   register_files;
   if (err==SUCCESS) { performInstall() };
   else { cancelInstall() };
}

In this arrangement, the actual execution of the installation is checked against the errors returned from the addition of files to the installation, which may itself have been conditioned on some verification of version and necessary disk space.

The actual install code used to execute the installation appears in the install.js file as follows:

if (err==SUCCESS)
  {
     err = performInstall(); 
        logComment("performInstall() returned: " + err);
  }
  else
  {
     cancelInstall(err);
	 logComment("cancelInstall() due to error: " + err);
  }
}
else
   cancelInstall(INSUFFICIENT_DISK_SPACE);

performInstall is the function used to execute the install once it has been initialized and loaded, and it is the last step to installing the software. Note that in the example above, the installation is cancelled if the error code from the file addition process returns success (0), and also cancelled outside the main block if the earlier verification process is not successful.

Note also the comments that indicate the success of various steps in the process--including the performInstall and cancelInstall steps--are written to the install log using the logComment, described in the following section.

Installation Logging

Logging is an important feature of the XPInstall API that can help you streamline and debug your installations. In the example in the Executing the Installation section and in many places in the installation script, the logComment API is used to write data to a log file that can then be reviewed when things don't go as planned.

The install log is created in the product directory by default (where the browser executable is). If the installation doesn't have proper permission, the install log is written to the user's profile directory. Respectively, these directories correspond to the "Program" and "Current User" keywords for the getFolder method.

Extending the Example

What does all this mean to you? How can this information be adapted for your own installations? In this final section, we describe the application of the XPInstall technology described here in the creation and deployment of a very simple installation script and installation archive (XPI).

Say you have a simple executable and a README file that goes with it, and you want to make it available for installation from a XPI. After putting these two files in a XPI (which, as described above, is simply a ZIP file with an install.js script at the top and a suffix of '.xpi'), the next step is to add an installation script to the XPI.

Minimally, the installation script must:

  • Call initInstall with the name and version of the executable (the version is not optional, though you may or may not use the version in subsequent installations or updates)
  • Find somewhere to put the installed files. In the example below, getFolder is used with the "Program" keyword to specify the browser's program directory as the target for installation. Since I am using NS6 right now on a Windows machine, that target directory is "C:\Program Files\Netscape\Netscape 6\".
  • Add files to the initialized installation using addFile.
  • Call performInstall to execute the installation.

Here is an example of small but complete installation script.

var xpiSrc = "cd_ripper.exe";
var xpiDoc = "README_cdrip";
initInstall("My CD Ripper", "cdrip", "1.0.1.7");
f = getFolder("Program");
setPackageFolder(f);
addFile(xpiSrc);
addFile(xpiDoc);
if (0 == getLastError())
	performInstall();		
else
	cancelInstall();

The example above shows this minimal installation. This install script does not include any version or disk space checking, very little error checking, only a single executable, no registration, and no commenting. It does, however, take the executable and the README file and install them on the user's system. Note also that for the installation script in a XPI to be automatically triggered from a web page, you must use a "trigger script." The following InstallTrigger function, called from an event handler on a regular web page, will point to the remotely-hosted XPI (called here 'cdrip.xpi') and trigger its installation:

function putIt() 
{  
  xpi={'CD_Ripper':'cdrip.xpi'};
  InstallTrigger.install(xpi);
}
...
<a href="#" onclick="putIt();">install the CD Ripper Now!</a>

See the InstallTrigger object in the XPInstall API Reference for more information on triggering installations.

Original Document Information

  • Author(s): Ian Oeschger
  • Last Updated Date: 01/26/2006
  • Copyright Information: Copyright (C) Ian Oeschger

Document Tags and Contributors

Tags: 
  • XPInstall
  • XPInstall_API_reference
 Contributors to this page: Sheppy, Mossop, BobChao, NickolayBot, Anguis
 Last updated by: Sheppy, Apr 15, 2014, 12:24:45 PM

  1. .htaccess ( hypertext access )
  2. <input> archive
  3. Add-ons
    1. Add-ons
    2. Firefox addons developer guide
    3. Interaction between privileged and non-privileged pages
    4. Tabbed browser
    5. bookmarks.export()
    6. bookmarks.import()
  4. Adding preferences to an extension
  5. An Interview With Douglas Bowman of Wired News
  6. Apps
    1. Apps
    2. App Development API Reference
    3. Designing Open Web Apps
    4. Graphics and UX
    5. Open web app architecture
    6. Tools and frameworks
    7. Validating web apps with the App Validator
  7. Archived Mozilla and build documentation
    1. Archived Mozilla and build documentation
    2. ActiveX Control for Hosting Netscape Plug-ins in IE
    3. Archived SpiderMonkey docs
    4. Autodial for Windows NT
    5. Automated testing tips and tricks
    6. Automatic Mozilla Configurator
    7. Automatically Handle Failed Asserts in Debug Builds
    8. BlackConnect
    9. Blackwood
    10. Bonsai
    11. Bookmark Keywords
    12. Building TransforMiiX standalone
    13. Chromeless
    14. Creating a Firefox sidebar extension
    15. Creating a Microsummary
    16. Creating a Mozilla Extension
    17. Creating a Release Tag
    18. Creating a Skin for Firefox/Getting Started
    19. Creating a Skin for Mozilla
    20. Creating a Skin for SeaMonkey 2.x
    21. Creating a hybrid CD
    22. Creating regular expressions for a microsummary generator
    23. DTrace
    24. Dehydra
    25. Developing New Mozilla Features
    26. Devmo 1.0 Launch Roadmap
    27. Download Manager improvements in Firefox 3
    28. Download Manager preferences
    29. Drag and Drop
    30. Embedding FAQ
    31. Embedding Mozilla in a Java Application using JavaXPCOM
    32. Error Console
    33. Exception logging in JavaScript
    34. Existing Content
    35. Extension Frequently Asked Questions
    36. Fighting Junk Mail with Netscape 7.1
    37. Firefox Sync
    38. Force RTL
    39. GRE
    40. Gecko Coding Help Wanted
    41. HTTP Class Overview
    42. Hacking wiki
    43. Help Viewer
    44. Helper Apps (and a bit of Save As)
    45. Hidden prefs
    46. How to Write and Land Nanojit Patches
    47. Introducing the Audio API extension
    48. Java in Firefox Extensions
    49. JavaScript crypto
    50. Jetpack
    51. Litmus tests
    52. Makefile.mozextension.2
    53. Microsummary topics
    54. Migrate apps from Internet Explorer to Mozilla
    55. Monitoring downloads
    56. Mozilla Application Framework
    57. Mozilla Crypto FAQ
    58. Mozilla Modules and Module Ownership
    59. Mozprocess
    60. Mozprofile
    61. Mozrunner
    62. Nanojit
    63. New Skin Notes
    64. Persona
    65. Plug-n-Hack
    66. Plugin Architecture
    67. Porting NSPR to Unix Platforms
    68. Priority Content
    69. Prism
    70. Proxy UI
    71. Remote XUL
    72. SXSW 2007 presentations
    73. Space Manager Detailed Design
    74. Space Manager High Level Design
    75. Standalone XPCOM
    76. Stress testing
    77. Structure of an installable bundle
    78. Supporting private browsing mode
    79. Table Cellmap
    80. Table Cellmap - Border Collapse
    81. Table Layout Regression Tests
    82. Table Layout Strategy
    83. Tamarin
    84. The Download Manager schema
    85. The life of an HTML HTTP request
    86. The new nsString class implementation (1999)
    87. TraceVis
    88. Treehydra
    89. URIScheme
    90. URIs and URLs
    91. Using Monotone With Mozilla CVS
    92. Using SVK With Mozilla CVS
    93. Using addresses of stack variables with NSPR threads on win16
    94. Venkman
    95. Video presentations
    96. Why Embed Gecko
    97. XML in Mozilla
    98. XPInstall
    99. XPJS Components Proposal
    100. XRE
    101. XTech 2005 Presentations
    102. XTech 2006 Presentations
    103. XUL Explorer
    104. XULRunner
    105. ant script to assemble an extension
    106. calICalendarView
    107. calICalendarViewController
    108. calIFileType
    109. xbDesignMode.js
  8. Archived open Web documentation
    1. Archived open Web documentation
    2. Browser Detection and Cross Browser Support
    3. Browser Feature Detection
    4. Displaying notifications (deprecated)
    5. E4X
    6. E4X Tutorial
    7. LiveConnect
    8. MSX Emulator (jsMSX)
    9. Old Proxy API
    10. Properly Using CSS and JavaScript in XHTML Documents
    11. Reference
    12. Scope Cheatsheet
    13. Server-Side JavaScript
    14. Sharp variables in JavaScript
    15. Standards-Compliant Authoring Tools
    16. Using JavaScript Generators in Firefox
    17. Window.importDialog()
    18. Writing JavaScript for XHTML
    19. XForms
    20. background-size
    21. forEach
  9. B2G OS
    1. B2G OS
    2. Automated Testing of B2G OS
    3. B2G OS APIs
    4. B2G OS add-ons
    5. B2G OS architecture
    6. B2G OS build prerequisites
    7. B2G OS phone guide
    8. Building B2G OS
    9. Building and installing B2G OS
    10. Building the B2G OS Simulator
    11. Choosing how to run Gaia or B2G
    12. Customization with the .userconfig file
    13. Debugging on Firefox OS
    14. Developer Mode
    15. Developing Firefox OS
    16. Firefox OS Simulator
    17. Firefox OS apps
    18. Firefox OS board guide
    19. Firefox OS developer release notes
    20. Firefox OS security
    21. Firefox OS usage tips
    22. Gaia
    23. Installing B2G OS on a mobile device
    24. Introduction to Firefox OS
    25. Mulet
    26. Open web apps quickstart
    27. Pandaboard
    28. PasscodeHelper Internals
    29. Porting B2G OS
    30. Preparing for your first B2G build
    31. Resources
    32. Running tests on Firefox OS: A guide for developers
    33. The B2G OS platform
    34. Troubleshooting B2G OS
    35. Using the App Manager
    36. Using the B2G emulators
    37. Web Bluetooth API (Firefox OS)
    38. Web Telephony API
    39. Web applications
  10. Beginner tutorials
    1. Beginner tutorials
    2. Creating reusable content with CSS and XBL
    3. Underscores in class and ID Names
    4. XML data
    5. XUL user interfaces
  11. Case Sensitivity in class and id Names
  12. Creating a dynamic status bar extension
  13. Creating a status bar extension
  14. Gecko Compatibility Handbook
  15. Getting the page URL in NPAPI plugin
  16. Index
  17. Inner-browsing extending the browser navigation paradigm
  18. Install.js
  19. JXON
  20. List of Former Mozilla-Based Applications
  21. List of Mozilla-Based Applications
  22. Localizing an extension
  23. MDN
    1. MDN
    2. Content kits
  24. MDN "meta-documentation" archive
    1. MDN "meta-documentation" archive
    2. Article page layout guide
    3. Blog posts to integrate into documentation
    4. Current events
    5. Custom CSS classes for MDN
    6. Design Document
    7. DevEdge
    8. Developer documentation process
    9. Disambiguation
    10. Documentation Wishlist
    11. Documentation planning and tracking
    12. Editing MDN pages
    13. Examples
    14. Existing Content/DOM in Mozilla
    15. External Redirects
    16. Finding the right place to document bugs
    17. Getting started as a new MDN contributor
    18. Landing page layout guide
    19. MDN content on WebPlatform.org
    20. MDN page layout guide
    21. MDN subproject list
    22. Needs Redirect
    23. Page types
    24. RecRoom documentation plan
    25. Remove in-content iframes
    26. Team status board
    27. Trello
    28. Using the Mozilla Developer Center
    29. Welcome to the Mozilla Developer Network
    30. Writing chrome code documentation plan
    31. Writing content
  25. MMgc
  26. Makefile - .mk files
  27. Marketplace
    1. Marketplace
    2. API
    3. Monetization
    4. Options
    5. Publishing
  28. Mozilla release FAQ
  29. Newsgroup summaries
    1. Newsgroup summaries
    2. Format
    3. Mozilla.dev.apps.firefox-2006-09-29
    4. Mozilla.dev.apps.firefox-2006-10-06
    5. mozilla-dev-accessibility
    6. mozilla-dev-apps-calendar
    7. mozilla-dev-apps-firefox
    8. mozilla-dev-apps-thunderbird
    9. mozilla-dev-builds
    10. mozilla-dev-embedding
    11. mozilla-dev-extensions
    12. mozilla-dev-i18n
    13. mozilla-dev-l10n
    14. mozilla-dev-planning
    15. mozilla-dev-platform
    16. mozilla-dev-quality
    17. mozilla-dev-security
    18. mozilla-dev-tech-js-engine
    19. mozilla-dev-tech-layout
    20. mozilla-dev-tech-xpcom
    21. mozilla-dev-tech-xul
    22. mozilla.dev.apps.calendar
    23. mozilla.dev.tech.js-engine
  30. Obsolete: XPCOM-based scripting for NPAPI plugins
  31. Plugins
    1. Plugins
    2. Adobe Flash
    3. External resources for plugin creation
    4. Logging Multi-Process Plugins
    5. Monitoring plugins
    6. Multi-process plugin architecture
    7. NPAPI plugin developer guide
    8. NPAPI plugin reference
    9. Samples and Test Cases
    10. Shipping a plugin as a Toolkit bundle
    11. Supporting private browsing in plugins
    12. The First Install Problem
    13. Writing a plugin for Mac OS X
    14. XEmbed Extension for Mozilla Plugins
  32. SAX
  33. Security
    1. Security
    2. Digital Signatures
    3. Encryption and Decryption
    4. Introduction to Public-Key Cryptography
    5. Introduction to SSL
    6. NSPR Release Engineering Guide
    7. SSL and TLS
  34. Solaris 10 Build Prerequisites
  35. Sunbird Theme Tutorial
  36. Table Reflow Internals
  37. Tamarin Tracing Build Documentation
  38. The Basics of Web Services
  39. Themes
    1. Themes
    2. Building a Theme
    3. Common Firefox theme issues and solutions
    4. Creating a Skin for Firefox
    5. Making sure your theme works with RTL locales
    6. Theme changes in Firefox 2
    7. Theme changes in Firefox 3
    8. Theme changes in Firefox 3.5
    9. Theme changes in Firefox 4
  40. Updating an extension to support multiple Mozilla applications
  41. Using IO Timeout And Interrupt On NT
  42. Using SSH to connect to CVS
  43. Using workers in extensions
  44. WebVR
    1. WebVR
    2. WebVR environment setup
  45. XQuery
  46. XUL Booster
  47. XUL Parser in Python