Question

This question is related to: How to execute a windows command from firefox addon?

I am developing an addon for thunderbird/firefox. Basically, I want to run an executable and get the stdout of this executable. To do so, the answer of the above stackoverflow post indicates, it is necessary to pipe the output of the program to an tmp file, which may be read in the end of the execution.

To run an external command I had a look at https://developer.mozilla.org/en-US/docs/XPCOM_Interface_Reference/nsIProcess. At the end there's a little example which I adopted to run any program with arguments.

To create the tmp file I knock this code from different sources:

// create a new tmp file
var ds = Components.classes["@mozilla.org/file/directory_service;1"].getService();
var dsprops = ds.QueryInterface(Components.interfaces.nsIProperties);
var tmpFile = dsprops.get("TmpD", Components.interfaces.nsIFile);
tmpFile.append("Query.tmp");
tmpFile.createUnique(tmpFile.NORMAL_FILE_TYPE, 0600);

To pipe the output of the executing file to the tmpfile, I append a pipe to the arguments to run:

args.push("> " + tmpFile.path);

And in the end I read the whole file content with the function readFile, which don't seem to be the problem.

In total the code looks like this until now:

// read the content of a file
function readFile(file) {
    var ioServ = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);
    var fileURI = ioServ.newFileURI(file);
    var fileChannel = ioServ.newChannel(fileURI.asciiSpec, null, null);
    var rawInStream = fileChannel.open();
    var scriptableInStream = Components.classes["@mozilla.org/scriptableinputstream;1"].createInstance(Components.interfaces.nsIScriptableInputStream);
    scriptableInStream.init(rawInStream);
    var available = scriptableInStream.available();
    var fileContents = scriptableInStream.read(available);
    scriptableInStream.close();
}

// run an external command from inside an addon
function runCMD(cmd, args) {
    // see: https://developer.mozilla.org/en-US/docs/XPCOM_Interface_Reference/nsIProcess
    // create an nsIFile for the executable
    var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsIFile);
    file.initWithPath(cmd);
    // create an nsIProcess
    var process = Components.classes["@mozilla.org/process/util;1"].createInstance(Components.interfaces.nsIProcess);
    process.init(file);
    // create a new tmp file
    var ds = Components.classes["@mozilla.org/file/directory_service;1"].getService();
    var dsprops = ds.QueryInterface(Components.interfaces.nsIProperties);
    var tmpFile = dsprops.get("TmpD", Components.interfaces.nsIFile);
    tmpFile.append("Query.tmp");
    tmpFile.createUnique(tmpFile.NORMAL_FILE_TYPE, 0600);
    // append the tmp file to the parameters
    args.push("> " + tmpFile.path);
    // Run the process.
    // If first param is true, calling thread will be blocked until called process terminates.
    // Second and third params are used to pass command-line arguments to the process.
    process.run(true, args, args.length);
    // ok, now get the content of the tmp file
    if (tmpFile.exists()) {
        var outStr = readFile(tmpFile);
        tmpFile.remove(false);
        return outStr;
    }
    return null
}

However I keep getting an empty line, while executing

runCMD("/usr/bin/env", ["echo", "foobar"]);

any ideas?

No correct solution

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