Javascript 在安装和升级基于Firefox插件SDK的扩展时强制重新启动

Javascript 在安装和升级基于Firefox插件SDK的扩展时强制重新启动,javascript,firefox,firefox-addon,firefox-addon-sdk,Javascript,Firefox,Firefox Addon,Firefox Addon Sdk,我有一个基于Firefox Jetpack插件SDK的扩展,它不是以最好的方式构建的——重新安装后,一些旧的XPCOM组件挂在内存中,无法注册新组件。因此,我需要在扩展更新/安装时强制重新启动浏览器。我知道旧版本默认会这样做,但这个版本是无重启的 所以我的问题是:如何强制浏览器在扩展升级时重新启动? 我查看了package.json,没有发现任何东西。我的期望是,如果您希望尝试将您的附加SDK扩展标记为非重启,那么您基本上就是SOL。生成一个使用标准无重启启动方法的扩展。因此,无论何时创建附加S

我有一个基于Firefox Jetpack插件SDK的扩展,它不是以最好的方式构建的——重新安装后,一些旧的XPCOM组件挂在内存中,无法注册新组件。因此,我需要在扩展更新/安装时强制重新启动浏览器。我知道旧版本默认会这样做,但这个版本是无重启的

所以我的问题是:如何强制浏览器在扩展升级时重新启动?
我查看了package.json,没有发现任何东西。

我的期望是,如果您希望尝试将您的附加SDK扩展标记为非重启,那么您基本上就是SOL。生成一个使用标准无重启启动方法的扩展。因此,无论何时创建附加SDK附加组件,实际上您都已经创建了一个由附加SDK包装的无重启附加组件

您可以在
jpm xpi
创建的install.rdf文件中更改以下行:
true


false

这将导致您的扩展被视为一个非重启的附加组件。Firefox和Mozilla插件将其视为一个扩展,需要重新启动才能启用/禁用

但是,这样做会导致附加组件无法正常工作。您的加载项的入口点永远不会被调用

因此,您必须自己强制重新启动

您需要存储一个首选项,该首选项指示您已重新启动或未重新启动(即,这样您就不会继续重新启动)。见:

您应该与用户一起打开/(),通知他们需要重新启动才能使加载项正常工作,并向他们提供此时重新启动或等待的选项。见:

在我的一个加载项中,需要重新启动以使更改完全生效(而不是重新启动只会导致部分效果)。我会通知用户这一需求,并从“选项”对话框中为他们提供选项。该对话框如下所示:

在这个对话框中,按钮
接受更改并重新启动Firefox
将执行它所说的操作,然后重新启动Firefox。我用于重新启动Firefox的代码是:

window.opener.content.document.getElementById('cmd_restartApp').doCommand();
这使用Firefox内置的重启功能来执行重启。因此,如果必须执行重启的确切方法或与此相关的任何内务管理发生变化,则无需保持代码更新

确切地说,您将如何调用该函数取决于您想要调用该函数时所处的上下文。在某种程度上,这将取决于您如何实现通知用户需要重新启动,并向用户提供现在或以后重新启动的选项。考虑到您在问题中没有指定这一点,因此不可能确切地告诉您需要使用哪些代码才能导致重新启动。但是,一般来说,您需要一个对Firefox基本窗口之一的引用。您可以通过各种方法中的任何一种来获得该引用,具体取决于您如何实现与用户的交互

一种方法是:

if (window === null || typeof window !== "object") {
    //If you do not already have a window reference, you need to obtain one:
    //  Add/remove a "/" to comment/un-comment the code appropriate for your add-on type.
    //* Add-on SDK:
    var window = require('sdk/window/utils').getMostRecentBrowserWindow();
    //*/
    /* Overlay and bootstrap (from almost any context/scope):
    var window=Components.classes["@mozilla.org/appshell/window-mediator;1"]
                         .getService(Components.interfaces.nsIWindowMediator)
                         .getMostRecentWindow("navigator:browser");        
    //*/
}
if (typeof document === "undefined") {
    //If there is no document defined, get it
    var document = window.content.document;
}

//Then restart:
document.getElementById('cmd_restartApp').doCommand();

上述代码的一部分是从我的其他答案中复制的,包括,或者从我写的一篇文章中复制的。

我的期望是,如果您希望尝试将您的附加SDK扩展标记为非重启的,那么您基本上是SOL。生成一个使用标准无重启启动方法的扩展。因此,无论何时创建附加SDK附加组件,实际上您都已经创建了一个由附加SDK包装的无重启附加组件

您可以在
jpm xpi
创建的install.rdf文件中更改以下行:
true


false

这将导致您的扩展被视为一个非重启的附加组件。Firefox和Mozilla插件将其视为一个扩展,需要重新启动才能启用/禁用

但是,这样做会导致附加组件无法正常工作。您的加载项的入口点永远不会被调用

因此,您必须自己强制重新启动

您需要存储一个首选项,该首选项指示您已重新启动或未重新启动(即,这样您就不会继续重新启动)。见:

您应该与用户一起打开/(),通知他们需要重新启动才能使加载项正常工作,并向他们提供此时重新启动或等待的选项。见:

在我的一个加载项中,需要重新启动以使更改完全生效(而不是重新启动只会导致部分效果)。我会通知用户这一需求,并从“选项”对话框中为他们提供选项。该对话框如下所示:

在这个对话框中,按钮
接受更改并重新启动Firefox
将执行它所说的操作,然后重新启动Firefox。我用于重新启动Firefox的代码是:

window.opener.content.document.getElementById('cmd_restartApp').doCommand();
这使用Firefox内置的重启功能来执行重启。因此,如果必须执行重启的确切方法或与此相关的任何内务管理发生变化,则无需保持代码更新

确切地说,您将如何调用该函数取决于您想要调用该函数时所处的上下文。在某种程度上,这将取决于您如何实现通知用户需要重新启动,并向用户提供现在或以后重新启动的选项。考虑到您在问题中没有指定这一点,因此不可能确切地告诉您需要使用哪些代码才能导致重新启动。但是,一般来说,您需要一个对Firefox基本窗口之一的引用。您可以通过各种方法中的任何一种来获得该引用,具体取决于您如何实现与用户的交互

一种方法是:

if (window === null || typeof window !== "object") {
    //If you do not already have a window reference, you need to obtain one:
    //  Add/remove a "/" to comment/un-comment the code appropriate for your add-on type.
    //* Add-on SDK:
    var window = require('sdk/window/utils').getMostRecentBrowserWindow();
    //*/
    /* Overlay and bootstrap (from almost any context/scope):
    var window=Components.classes["@mozilla.org/appshell/window-mediator;1"]
                         .getService(Components.interfaces.nsIWindowMediator)
                         .getMostRecentWindow("navigator:browser");        
    //*/
}
if (typeof document === "undefined") {
    //If there is no document defined, get it
    var document = window.content.document;
}

//Then restart:
document.getElementById('cmd_restartApp').doCommand();
上述代码的一部分是从我的其他答案中复制的,包括,