【问题标题】:Can't create javascript XPCOM service for Firefox extension无法为 Firefox 扩展创建 javascript XPCOM 服务
【发布时间】:2012-06-07 09:10:19
【问题描述】:

两天多来,我一直在用头撞这堵特殊的砖墙。我正在尝试创建用于 Firefox 扩展的 XPCOM 服务,但无法初始化组件,并在 Firefox 的错误控制台中显示以下错误。

Timestamp: 07/06/2012 09:23:28 Error: uncaught exception: [Exception... 
"Component returned failure code: 0x80570016 (NS_ERROR_XPC_GS_RETURNED_FAILURE)
[nsIJSCID.getService]"  nsresult: "0x80570016 (NS_ERROR_XPC_GS_RETURNED_FAILURE)"
location: "JS frame :: chrome://logger/content/logger.js :: <TOP_LEVEL> :: line 21"
data: no]

我使用ted.mielczarek.org 的优秀样板生成器将组件减少到最低限度。组件代码如下...

const nsISupports = Components.interfaces.nsISupports;
const CLASS_ID = Components.ID("808e1607-caea-418c-b563-d9fe1df6ee08");
const CLASS_NAME = "Test component";
const CONTRACT_ID = "@test/loggerservice;1";

function LoggerService() {
  this.wrappedJSObject = this;
}

LoggerService.prototype = {
  QueryInterface: function(aIID)
  {
    if (!aIID.equals(nsISupports))
      throw Components.results.NS_ERROR_NO_INTERFACE;
    return this;
  }
}

创建模块和工厂接口的样板的其余部分保持不变。

chrome.manifest 文件长这样...

content   logger                 chrome/content/
skin      logger   classic/1.0   chrome/skin/
locale    logger   en-US         chrome/locale/en-US/

component {808e1607-caea-418c-b563-d9fe1df6ee08} components/loggerservice.js
contract @test/loggerservice;1 {808e1607-caea-418c-b563-d9fe1df6ee08}

overlay chrome://browser/content/browser.xul chrome://logger/content/logger-overlay.xul
style   chrome://global/content/customizeToolbar.xul chrome://logger/skin/overlay.css

最后,logger-overlay.xul 文件包含一个脚本文件 - logger.js - 它尝试使用以下代码获取对 LoggerService 组件的引用...

this.loggerService = Components.classes["@test/logger;1"].getService().wrappedJSObject;

在 firefox 错误控制台中报告的正是这一行。

我看不出我可以使它变得多么简单 - 任何见解都将非常感激。

【问题讨论】:

    标签: javascript firefox-addon xpcom


    【解决方案1】:

    这是一个不错的样板生成器,但不幸的是它已经过时了。一方面,您应该使用XPCOMUtils,这将摆脱大部分样板文件。更重要的是,这个样板生成器还没有更新为XPCOM changes in Gecko 2.0,并且定义了NSGetModule 函数而不是NSGetFactory。但是,像这样的模块代码应该可以工作:

    Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
    
    function LoggerService() {
      this.wrappedJSObject = this;
    }
    
    LoggerService.prototype = {
      classID: Components.ID("808e1607-caea-418c-b563-d9fe1df6ee08"),
      classDescription: "Test component",
      contractID: "@test/loggerservice;1",
    
      QueryInterface: XPCOMUtils.generateQI([])
    }
    
    if ("generateNSGetFactory" in XPCOMUtils)
      var NSGetFactory = XPCOMUtils.generateNSGetFactory([LoggerService]);  // 2.0+
    else
      var NSGetModule = XPCOMUtils.generateNSGetModule([LoggerService]);    // 1.9.x
    

    如果您的扩展不需要与 Firefox 3.6 兼容,您可以删除 NSGetModule 代码。您还可以删除classDescriptioncontractID 属性,这些属性已经在chrome.manifest 中指定。

    注意:如果您只需要一个在整个浏览会话期间都存在并且可以从任何地方访问的对象,那么 JavaScript code module 将是更好的选择 - 没有 XPCOM 样板文件,也没有 @ 987654331@黑客。

    【讨论】:

    • 弗拉基米尔 - 谢谢 - 最佳建议!使用 XPCOMUtils 后,代码现在也变得更简洁了。我现在终于可以开始并发展我的服务了!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多