How to reference an external binary by URI?
-
21-06-2021 - |
题
I have a Thunderbird extension that mutates message bodies using an external executable. Currently I do a hack-job and just place this executable in /tmp/someBinary
and call it like so:
var exe = FileUtils.File("/tmp/someBinary");
var proc = Components.classes["@mozilla.org/process/util;1"]
.createInstance(Components.interfaces.nsIProcess);
proc.init(exe);
var args = [msgBody.path];
proc.run(true, args, args.length);
This is obviously stupid, it would be nice to call it via URI and bundle the executable with the application. Sadly, my limited JS means I only came up with the following:
var URL = ios.newURI("chrome://myExtension/content/someBinary",null,null);
var exe = URL.QueryInterface(Components.interfaces.nsIFileURL).file;
But that isn't quite right. Is there a normal way to get this done?
解决方案
You would need to ask the chrome registry what the URL you have there resolves to:
var chromeRegistry = Components.classes["@mozilla.org/chrome/chrome-registry;1"]
.getService(Components.interfaces.nsIChromeRegistry);
var URL = ios.newURI("chrome://myExtension/content/someBinary", null, null);
URL = chromeRegistry.convertChromeURL(URL);
var exe = null;
if (URL instanceof Components.interfaces.nsIFileURL)
exe = URL.file;
Note that a chrome://
URL won't necessarily resolve into a file://
URL. Normally an extension is installed as a packed XPI file and the will only get a link to a file inside this archive, not something that the OS can execute. So you will need to specify the <em:unpack>
flag in your install.rdf
file.
This approach is simple but degrades startup performance (the extension manager doesn't unpack extensions by default for a reason). So a better solution might be copying your executable into the temp directory first time you need it.