首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >选择Firefox外接程序目录中的文件

选择Firefox外接程序目录中的文件
EN

Stack Overflow用户
提问于 2014-07-23 02:23:33
回答 2查看 1.1K关注 0票数 0

为了简单起见,我正在将基于XUL的Firefox插件转换为基于SDK的版本。我在基于XUL的版本中使用的XPCOM模块似乎工作正常,但ci.nsIFile的行为却有所不同。

我不知道如何导航到smartProxy.py,它目前位于目录的最高层。

在XUL版本中,smartProxy.py位于chrome/bin/martproxy.py上。我使用下面的命令来执行这个程序,它运行时没有错误。

代码语言:javascript
运行
复制
getExeFile: function() {
    var file = cc["@mozilla.org/file/directory_service;1"].getService(ci.nsIProperties).get("ProfD", ci.nsIFile);
    file.append("smartProxy.py");
    return file;
},

下面是它的执行位置,应该给出加载项是如何工作的完整图片。

代码语言:javascript
运行
复制
start: function() {
    if (this.process && this.process.isRunning)
        return;
    this.process = cc["@mozilla.org/process/util;1"].createInstance(ci.nsIProcess);
    this.process.init(this.getExeFile());
    this.process.runAsync([], 0, this.processObserver);
    this.setProxy();
    this.executeObservers();
},

如何找到smartProxy.py以便能够执行?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-07-23 13:29:45

现在,nsIProcess API只支持从Firefox运行外部命令。你已经为自己弄明白了这一点。

打包python脚本。

SDK将只打包某些文件/位置。将python脚本放在data/文件夹中是最简单的,因为这是SDK将打包所有文件的位置之一。

nsIProcess

nsIProcess需要一个可执行文件,而该文件实际上需要是一个真正的文件(而不仅仅是包含在XPI中的文件,在默认情况下,XPI不需要解压缩)。

因此,有两种情况我们可能需要处理:

  1. 文件是真正的文件-只需执行它。
  2. 文件被打包--需要将数据提取/复制到一个(临时的)真实文件中并执行该文件。

下面的代码处理这两种情况。我在OSX (*nix,因此也应该在Linux或BSD上)和Windows上测试并运行它,无论是否使用em:unpack (而且您应该避免em:unpack)。

代码语言:javascript
运行
复制
const self = require("sdk/self");

const {Cc, Ci, Cu} = require("chrome");

Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/NetUtil.jsm");

const ChromeRegistry = Cc["@mozilla.org/chrome/chrome-registry;1"].
                       getService(Ci.nsIChromeRegistry);
const ResProtoHandler = Services.io.getProtocolHandler("resource").
                        QueryInterface(Ci.nsIResProtocolHandler);

function copyToTemp(uri, callback) {
  // Based on https://stackoverflow.com/a/24850643/484441
  let file = Services.dirsvc.get("TmpD", Ci.nsIFile);
  file.append(self.name + "_" + uri.spec.replace(/^.+\//, ""));
  file.createUnique(Ci.nsIFile, 0o0700);
  NetUtil.asyncFetch(uri, function(istream) {
    let ostream = Cc["@mozilla.org/network/file-output-stream;1"].
                  createInstance(Ci.nsIFileOutputStream);
    ostream.init(file, -1, -1, Ci.nsIFileOutputStream.DEFER_OPEN);
    NetUtil.asyncCopy(istream, ostream, function(result) {
      callback && callback(file, result);
    });
  });
}

function runProcessAndThen(file, callback) {
  console.log("running", file.path);

  let proc = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess);
  try {
    // Set executable bit on unix
    file.permissions = file.permissions | 0o0500;
  }
  catch (ex) {
    // Might throw?!
  }
  proc.init(file);
  proc.runAsync([], 0, callback);
}

function runFromURIWithPotentialCopy(uri, callback) {
  if (!uri.spec) {
    uri = Services.io.newURI(uri, null, null);
  }
  if (uri.scheme === "resource") {
    // Need to resolve futher. Strip one layer of indirection and recursively
    // call ourselves.
    uri = Services.io.newURI(ResProtoHandler.resolveURI(uri), null, null);
    return runFromURIWithPotentialCopy(uri, callback);
  }

  if (uri.scheme === "chrome") {
    // Need to resolve futher. Strip one layer of indirection and recursively
    // call ourselves.
    return runFromURIWithPotentialCopy(ChromeRegistry.convertChromeURL(uri), callback);
  }

  if (uri instanceof Ci.nsIFileURL) {
    // A plain file we can execute directly.
    return runProcessAndThen(uri.file, callback);
  }

  if (uri instanceof Ci.nsIJARURI) {
    // A packaged file (in an XPI most likely).
    // Need to copy the data into some plain file and run the result.
    return copyToTemp(uri, function(f) {
      runProcessAndThen(f, function() {
        try {
          // Clean up after ourselves.
          f.remove(false);
        }
        catch (ex) {
          console.error("Failed to remove tmp file again", ex);
        }
        callback.apply(null, arguments);
      });
    });
  }

  throw new Error("Cannot handle URI");
}

function afterRun(subject, topic, data) {
  console.log(subject, topic, data);
}

function runFileFromDataDirectory(name, callback) {
  try {
    runFromURIWithPotentialCopy(self.data.url(name), callback);
  }
  catch (ex) {
    console.error(ex);
  }
}

runFileFromDataDirectory("test.py", afterRun);

运行脚本

运行脚本(相对于完整的二进制文件)可能比较棘手。例如,在Python的情况下,需要告诉*nix OSes有一个解释器和它是什么,这是由shebang完成的。在Windows上,Python需要与.py文件类型注册一起安装,默认安装程序将这样做,而不是“可移植”版本。

票数 5
EN

Stack Overflow用户

发布于 2014-07-23 08:57:41

嘿,伙计,我刚在sdk上查了些东西。不要因为引用的那些“性能问题”而在install.rdf中进行解压缩。相反,只需将其放在数据文件夹中即可。而不是像这样访问它:

APIs/self

代码语言:javascript
运行
复制
var self = require("sdk/self");
var py = self.data.url("my-panel-content.html")
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24900845

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档