Question

If you are developing an extension for one of the mozilla applications (e.g. Firefox, Thunderbird, etc.) you define a extension id in the install.rdf.

If for some reason you need to know the extension id e.g. to retrieve the extension dir in local file system (1) or if you want to send it to a webservice (useage statistic) etc. it would be nice to get it from the install.rdf in favour to have it hardcoded in your javascript code.

But how to access the extension id from within my extension?

1) example code:

var extId = "myspecialthunderbirdextid@mydomain.com";
var filename = "install.rdf";
var file = extManager.getInstallLocation(extId).getItemFile(extId, filename);
var fullPathToFile = file.path;
Was it helpful?

Solution

I'm fairly sure the 'hard-coded ID' should never change throughout the lifetime of an extension. That's the entire purpose of the ID: it's unique to that extension, permanently. Just store it as a constant and use that constant in your libraries. There's nothing wrong with that.

What IS bad practice is using the install.rdf, which exists for the sole purpose of... well, installing. Once the extension is developed, the install.rdf file's state is irrelevant and could well be inconsistent.

"An Install Manifest is the file an Add-on Manager-enabled XUL application uses to determine information about an add-on as it is being installed" [1]

To give it an analogy, it's like accessing the memory of a deleted object from an overflow. That object still exists in memory but it's not logically longer relevant and using its data is a really, really bad idea.

[1] https://developer.mozilla.org/en/install_manifests

OTHER TIPS

Like lwburk, I don't think its available through Mozilla's API's, but I have an idea which works, but it seems like a complex hack. The basic steps are:

  1. Set up a custom resource url to point to your extension's base directory
  2. Read the file and parse it into XML
  3. Pull the id out using XPath

Add the following line to your chrome.manifest file

resource    packagename-base-dir chrome/../

Then we can grab and parse the file with the following code:

function myId(){
    var req = new XMLHttpRequest();

    // synchronous request
    req.open('GET', "resource://packagename-base-dir/install.rdf", false); 
    req.send(null);

    if( req.status !== 0){
        throw("file not found");
    }

    var data = req.responseText;

    // this is so that we can query xpath with namespaces
    var nsResolver = function(prefix){
        var ns = {
            "rdf" : "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
            "em" : "http://www.mozilla.org/2004/em-rdf#"
        };
        return ns[prefix] || null;
    };

    var parser = CCIN("@mozilla.org/xmlextras/domparser;1", Ci.nsIDOMParser);
    var doc = parser.parseFromString(data, "text/xml");
    // you might have to change this xpath expression a bit to fit your setup
    var myExtId = doc.evaluate("//em:targetApplication//em:id", doc, nsResolver, 
                            Ci.nsIDOMXPathResult.FIRST_ORDERED_NODE_TYPE, null);

    return myExtId.singleNodeValue.textContent;
}

I chose to use a XMLHttpRequest(as opposed to simply reading from a file) to retrieve the contents since in Firefox 4, extensions aren't necessarily unzipped. However, XMLHttpRequest will still work if the extension remains packed (haven't tested this, but have read about it).

Please note that resource URL's are shared by all installed extensions, so if packagename-base-dir isn't unique, you'll run into problems. You might be able to leverage Programmatically adding aliases to solve this problem.

This question prompted me to join StackOverflow tonight, and I'm looking forward participating more... I'll be seeing you guys around!

As Firefox now just uses Chrome's WebExtension API, you can use @serg's answer at How to get my extension's id from JavaScript?:

You can get it like this (no extra permissions required) in two different ways:

  1. Using runtime api: var myid = chrome.runtime.id;

  2. Using i18n api: var myid = chrome.i18n.getMessage("@@extension_id");

I can't prove a negative, but I've done some research and I don't think this is possible. Evidence:

The interface does allow you to retrieve a full list of installed extensions, so it's possible to retrieve information about your extension using something other than the ID. See this code, for example:

var em = Cc['@mozilla.org/extensions/manager;1']
  .getService(Ci.nsIExtensionManager);
const nsIUpdateItem = Ci.nsIUpdateItem;

var extension_type = nsIUpdateItem.TYPE_EXTENSION;
items = em.getItemList(extension_type, {});
items.forEach(function(item, index, array) {
    alert(item.name + " / " + item.id + " version: " + item.version);
});

But you'd still be relying on hardcoded properties, of which the ID is the only one guaranteed to be unique.

Take a look on this add-on, maybe its author could help you, or yourself can figure out:

[Extension Manager] Extended is very simple to use. After installing, just open the extension manager by going to Tools and the clicking Extensions. You will now see next to each extension the id of that extension.

(Not compatible yet with Firefox 4.0)

https://addons.mozilla.org/firefox/addon/2195

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top