[SOLVED] How an add-on (legacy add-on) can retrieve its own install.rdf <em:version>

Hi all,

I ve googled for a while and can’t find any answer to this question mentioned in the title of this topic.

You can imagine that I don’t want to hardcode this version in JS code.

Thanks for your replies.

Here is some very old code I dig up from a project where we had to read install.rdf content.

First, we were getting the location where the extension is located at via

AddonManager.getAddonByID("YOUR_ADDON_GUID", function(addon){
    var addonLocation = addon.getResourceURI("").QueryInterface(Components.interfaces.nsIFileURL).path;
});

Then you can use the value of addonLocation to open your file with something like this

var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
file.initWithPath(addonLocation + "/install.rdf");
if (file.exists()) {
    var content = "";
    var fstream = Components.classes["@mozilla.org/network/file-input-stream;1"].createInstance(Components.interfaces.nsIFileInputStream);
    var is = Components.classes["@mozilla.org/network/file-input-stream;1"].createInstance( Components.interfaces.nsIFileInputStream );
    is.init(file, 0x01, 00004, null);
    var sis = Components.classes["@mozilla.org/scriptableinputstream;1"].createInstance( Components.interfaces.nsIScriptableInputStream );
    sis.init(is);
    content = sis.read(sis.available());
    is.close();
    sis.close();
} 

Let me know if this works for you.

You might also try:

var version;
  if ("@mozilla.org/extensions/manager;1" in CC) {
    // Pre-Gecko 2.0
    version = CC["@mozilla.org/extensions/manager;1"]
      .getService(CI.nsIExtensionManager)
      .getItemForID(uuid)
      .version || "0.0";
  } else {
    // Post-Gecko 2.0
    Components.utils.import("resource://gre/modules/AddonManager.jsm");
    AddonManager.getAddonByID(uuid, function(addon) {
      // addon is null when this code is running not packaged as XPI (i.e., debug/dev mode)
      version = addon ? addon.version : "0.0";
    });
  }

You can use Ci.nsIVersionComparator to compare version numbers.

let vc = CC["@mozilla.org/xpcom/version-comparator;1"].getService(CI.
    nsIVersionComparator);
vc.compare(version, "18.0a1") < 0;

Hi Sylvain,

Thanks for your code.

I ve just a problem when calling file.InitWithPath()

In browser console I notice :

1498856156851 addons.manager WARN Exception calling callback: [Exception… “Component returned failure code: 0x80520001 (NS_ERROR_FILE_UNRECOGNIZED_PATH) [nsILocalFile.initWithPath]” nsresult: “0x80520001 (NS_ERROR_FILE_UNRECOGNIZED_PATH)” location: “JS frame :: chrome://asipsante/content/overlay.js :: onLoad/< :: line 231” data: no] Stack trace: onLoad/<()@overlay.js:231 < safeCall()@resource://gre/modules/AddonManager.jsm:193 < makeSafe/<()@resource://gre/modules/AddonManager.jsm:208

I see the path is like: /C/Users/Bertrand/AppData/Roaming/…

How do I transform it to a real Windows path ?

Thanks.

If you use my approach, you do not need to worry about paths.

1 Like

I have solved my problem. Here is the code.

AddonManager.getAddonByID(extensionID, function(addon) {
			  
			  function /*String*/ getOSName(platform) {
				if(platform.indexOf("Win", 0)   != -1){
				  var myAgent = navigator.userAgent;
				  if (myAgent.indexOf("Win64", 0) != -1 || myAgent.indexOf("x64", 0) != -1)
					return "Win64";
				  return "Win32"; 
				}
				if(platform.indexOf("Linux", 0) != -1)
				  return "Linux";
				if(platform.indexOf("Mac", 0)   != -1)
				  return "Mac";
				return "Unknown";
			  };
			  
			  var chemin = addon.getResourceURI("").QueryInterface(Components.interfaces.nsIFileURL).path;
			  prompts.alert(null, "Test Extension", "Original path: " + chemin);
			  try {
					var /* nsILocalFile */ file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
					var osName = navigator.platform;
					osName = getOSName(osName);
				    if(osName == "Win32" || osName == "Win64") {
						chemin = chemin.substring(1, chemin.length );
						chemin = chemin.replace(/\//g,"\\");
				    }
					prompts.alert(null, "Test Extension", "Normalized path: " + chemin);
				    file.initWithPath(chemin + "install.rdf");
				    if (file.exists()) {
						var content = "";
						var fstream = Components.classes["@mozilla.org/network/file-input-stream;1"].createInstance(Components.interfaces.nsIFileInputStream);
						var is = Components.classes["@mozilla.org/network/file-input-stream;1"].createInstance( Components.interfaces.nsIFileInputStream );
						is.init(file, 0x01, 00004, null);
						var sis = Components.classes["@mozilla.org/scriptableinputstream;1"].createInstance( Components.interfaces.nsIScriptableInputStream );
						sis.init(is);
						content = sis.read(sis.available());
						var pos = content.indexOf("<em:version>");
						var pos_2 = content.indexOf("</em:version>");
						var my_ver = content.substring(pos + 12, pos_2);
						prompts.alert(null, "Test Extension", my_ver);
						is.close();
						sis.close();
					}
			  }
			  catch(e) {
				  prompts.alert(null, "Test Extension", e);
			  }
		  }

Sylvain & Eric, thanks again for your help.

Regards.

1 Like

Quite strange that you would choose to write so much code when you can get the information you need with just 2 lines, regardless of operating system and without specifying any filenames or paths:

Components.utils.import("resource://gre/modules/AddonManager.jsm");
AddonManager.getAddonByID(uuid, function(addon) { let version = addon ? addon.version : "0.0"; });