此问题与:How to execute a windows command from firefox addon?
有关我正在为thunderbird / firefox开发一个插件。基本上,我想运行一个可执行文件并获取此可执行文件的标准输出。为此,上面的stackoverflow帖子的答案表明,有必要将程序的输出传递给tmp文件,该文件可以在执行结束时读取。
要运行外部命令,我看了https://developer.mozilla.org/en-US/docs/XPCOM_Interface_Reference/nsIProcess。最后,我采用了一个小例子来运行任何带参数的程序。
要创建tmp文件,我会从不同来源敲取此代码:
// 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);
为了将执行文件的输出传递给tmpfile,我将一个管道附加到要运行的参数:
args.push("> " + tmpFile.path);
最后我用readFile函数读取整个文件内容,这似乎不是问题。
到目前为止,代码总是如此:
// 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
}
然而,在执行
时,我一直得到一个空行runCMD("/usr/bin/env", ["echo", "foobar"]);
任何想法?