Using nsIXULAppInfo

Starting with Mozilla/XULRunner 1.8, there now is a way to find out which application, application version, and Gecko version your code is running on.

This is useful, for example, for extensions that support several Mozilla-based applications or several versions of a single application. This is not useful for scripts on webpages, which should continue using the navigator object when it's not possible to rely on feature-detection.

nsIXULAppInfo interface

To distinguish between different Mozilla-based applications, use the frozen nsIXULAppInfo interface. The following sections provide a few examples of using nsIXULAppInfo from JavaScript.

Note that while Firefox 1.5, Thunderbird 1.5, and XULRunner 1.8-based applications support nsIXULAppInfo, older applications, such as Firefox and Thunderbird 1.0, do not support it. You'll need to have additional code for those older versions.

Getting nsIXULAppInfo

To get a component implementing nsIXULAppInfo use this code:

var appInfo = Components.classes["@mozilla.org/xre/app-info;1"]
                        .getService(Components.interfaces.nsIXULAppInfo);

(For explanation see this Creating XPCOM article.)

Getting application information

After you obtained the app info component, you can read its properties to get the application's ID, human-readable name, version, platform version, etc. For complete list of nsIXULAppInfo's properties, please see nsIXULAppInfo interface description.

ID

You can tell which application you're running under using the nsIXULAppInfo.ID property.

const FIREFOX_ID = "{ec8030f7-c20a-464f-9b0e-13a3a9e97384}";
const THUNDERBIRD_ID = "{3550f703-e582-4d05-9a08-453d09bdfdc6}";
const SEAMONKEY_ID = "{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}";
var appInfo = Components.classes["@mozilla.org/xre/app-info;1"]
                        .getService(Components.interfaces.nsIXULAppInfo);
if(appInfo.ID == FIREFOX_ID) {
  // running under Firefox
} else if(appInfo.ID == THUNDERBIRD_ID) {
  // running under Thunderbird
} else if(appInfo.ID == SEAMONKEY_ID) {
  // running under SeaMonkey
} else {
  // another app
}

Note: you could also use nsIXULAppInfo.name, which is a human-readable name for the application, such as "Firefox", "Thunderbird" or "SeaMonkey", but who knows, maybe they'll rename it again!

Version

Sometimes you need to know the version of the application your code is running under. For example, one of unfrozen functions you're relying on was changed.

Note: nsIXULAppInfo provides information about the application and the platform, be careful to use the right one, especially when dealing with XULRunner-based applications.

In such cases, you probably want to check nsIXULAppInfo.version and/or nsIXULAppInfo.appBuildID. The latter is useful if you're trying to support nightly development builds of the application, and the former can be useful if you only support official releases, and to distinguish between branch and trunk builds.

Example 1: checking Firefox version

// assuming we're running under Firefox
var appInfo = Components.classes["@mozilla.org/xre/app-info;1"]
                        .getService(Components.interfaces.nsIXULAppInfo);
var versionChecker = Components.classes["@mozilla.org/xpcom/version-comparator;1"]
                               .getService(Components.interfaces.nsIVersionComparator);
if(versionChecker.compare(appInfo.version, "1.5") >= 0) {
  // running under Firefox 1.5 or later
}

See nsIVersionComparator for details

Example 2: dealing with nightlies

var appInfo = Components.classes["@mozilla.org/xre/app-info;1"]
                        .getService(Components.interfaces.nsIXULAppInfo);
if(appInfo.appBuildID >= "2005093006") {
  // running on a build after 2005093006
}

You shouldn't rely on build IDs for releases, as build ID might be different for custom build or a localized version of an application.

Platform version

nsIXULAppInfo provides version information about both the XUL application (such as Firefox) and the platform (i.e. Gecko or XULRunner). For example, in Firefox 1.5 beta 2 application version is 1.4.1 and platform version is 1.8b5. Be careful to use the information you need, especially when dealing with XULRunner-based applications.

Obtaining platform version information is done like this:

var appInfo = Components.classes["@mozilla.org/xre/app-info;1"]
                        .getService(Components.interfaces.nsIXULAppInfo);
var platformVer = appInfo.platformVersion;
var platformBuildID = appInfo.platformBuildID;

Getting nsIXULAppInfo in xpcshell tests

In Firefox 21, a testing module was added that provides access to app info during the execution of xpcshell tests. See Bug 809920, and in summary:

// Work around the fact that xpcshell doesn't have a proper app-info XPCOM object.
Cu.import("resource://testing-common/AppInfo.jsm");
updateAppInfo();

Older versions

As stated above, older Mozilla 1.7-based applications do not support nsIXULAppInfo. You'll have to write additional code if you choose to support those versions.

For example, Firefox and Thunderbird 1.0 stored their ID in the app.id preference (and their version in app.version), so you could use code like this to find out what application you're running under:

function getAppID() {
  var id;
  if("@mozilla.org/xre/app-info;1" in Components.classes) {
    // running under Mozilla 1.8 or later
    id = Components.classes["@mozilla.org/xre/app-info;1"]
                   .getService(Components.interfaces.nsIXULAppInfo).ID;
  } else {
    try {
      id = Components.classes["@mozilla.org/preferences-service;1"]
                     .getService(Components.interfaces.nsIPrefBranch)
                     .getCharPref("app.id");
    } catch(e) {
      // very old version
      dump(e);
    }
  }
  return id;
}
alert(getAppID());

See also