Mozilla 插件首先执行代码 运行

Mozilla Add-On Execute code on first run

我目前正在构建一个插件,我想在第一个 运行 上执行特定代码。更具体地说,我想单击我的添加按钮,浏览我的文件和 select 一个可执行文件。这个浏览过程应该只在第一个 运行 上完成,因为我希望我的按钮 "remember" 在第一个 运行.

之后打开这个特定文件
jetpack.future.import("me");

var buttons = require('sdk/ui/button/action');

var button = buttons.ActionButton({
  id: "execute-jar",
  label: "Download Report",
  icon: {
    "16": "./icon-16.png",
    "32": "./icon-32.png",
    "64": "./icon-64.png"
  },
  onClick: handleClick
});

jetpack.me.onFirstRun(function(){    jetpack.notifications.show("Oh boy, I'm installed!");});

function handleClick(state) {   

    let {Cc, Ci} = require('chrome');
    var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
    file.initWithPath("C:\Users\QaziWa\DownloadReportPPE.jar");

    if(file.exists()){
        file.reveal();
        file.launch();
    }
    else {
        console.log('Failed.');
    }
}

我在 MDN 上找到了这个:https://developer.mozilla.org/en-US/docs/Archive/Mozilla/Jetpack/Meta/Me

但是,这是存档的东西,当我尝试这个时,我的代码没有成功并得到:"Message: ReferenceError: jetpack is not defined"。

此时我很困惑,因为我查看了几个我能找到的与我想要的相关的问题,但我不知道如何在我的附加组件中实现这个急需的功能。有人可以指出正确的方向或提供一些有效代码的示例吗?

编辑:为清楚起见:我不想对路径进行硬编码。我打算添加允许用户 select 他们希望执行的文件的功能。我的主要问题是如何仅在第一个 运行?

上执行某个代码块

具有第一个运行 代码的一般情况是您使用某种存储在preference to indicate if you have run the code, or not. Preferences are what are used within Firefox to store simple data across application restarts. The flag can be any of multiple types (string, number, boolean, etc.). You just have to have a value which you can test to see if you have run your first-run code. The general case of this is discussed on MDN in Appendix B: Install and Uninstall Scripts 中的标志,但该页面不是特定于SDK 的。当您的附加代码开始 运行ning 时,您然后测试该标志是否表明您已经 运行 您的第一个 运行 代码。如果标志表明您没有 运行 第一个 运行 代码,您 运行 该代码并设置标志以表明它已经 运行。你可以稍微修改一下,让代码在升级到新版本时只有 运行(只是另一个标志)等

在这种情况下,我们还需要在 Firefox 重新启动时存储选择的用户 filename/path。鉴于我们已经需要存储该信息,并且这是我们需要第一个 运行 代码获取的信息,因此 chosenFilename 的有效性也可以用作 运行 的标志第一个-运行 代码。因此,您将所选文件的完整 filename/path 存储为 preference。如果该首选项不包含文件名,那么您 运行 文件的 selection logic/browse(您的第一个 运行 代码)。

在这种情况下,我们还 运行 如果在我们尝试打开文件时发现存储的文件不存在(例如用户 deleted/moved文件)。显然,您还应该有一种方法让用户手动启动文件选择器。幸运的是,simple-prefs system takes care of that for us when we declare the type as file. A "Browse" 按钮将显示在选项对话框中,用户可以使用该按钮手动 select 不同的文件。

大致如下:

let {Cc, Ci} = require('chrome');
let preferences = require("sdk/simple-prefs").prefs;
let winUtils = require("sdk/window/utils");
const nsIFilePicker = Ci.nsIFilePicker;

function chooseFilename(){
    //If you only want .jar files then you would specify that in the filter(s):
    preferences.chosenFilename = browseForFilePath(nsIFilePicker.filterAll);
    //Just assume that it is valid. Should verify here that filename is valid.
}

function openChosenFilename() {   
    let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
    file.initWithPath(preferences.chosenFilename);
    while(!file.exists()){
        //The file we had is no longer valid. We need a valid filename so try choosing it
        // again. Keep doing so until it actually exists.
        chooseFilename();
        file.initWithPath(preferences.chosenFilename);
    }
    return file;
}

//The following function was copied from promptForFile(), then modified: 
//https://developer.mozilla.org/en-US/Add-ons/SDK/Tutorials/Creating_reusable_modules
function browseForFilePath(fileFilters) {
    let filePicker = Cc["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
    let recentWindow = winUtils.getMostRecentBrowserWindow();
    filePicker.init(recentWindow, "Select a file", nsIFilePicker.modeOpen);
    filePicker.appendFilters(fileFilters);
    let path = "";
    let status = filePicker.show();
    if (status === nsIFilePicker.returnOK || status === nsIFilePicker.returnReplace) {
        // Get the path as string.
        path = filePicker.file.path;
    }
    return path; //"" if invalid
}

if(preferences.chosenFilename.length<5) {
    //This is our first run code. We only run it if the length of the chosenFilename 
    //  is less than 5 (which is assumed to be invalid).
    //  You can have any first run code here. You just need to have the 
    //  preference you test for (which could be a string, boolean value, number, whatever) 
    //  be set prior to exiting this if statement. In this specific case,
    //  it is a filename. Given that we also want to store the filename persistent
    //  across Firefox restarts we are checking for filename being stored as a preference
    //  instead of an additional flag that says we have already run this code.
    chooseFilename();
}

let file = openChosenFilename();
file.reveal();
file.launch();

您的package.json还需要:

"preferences": [{
    "name": "chosenFilename",
    "title": "Filename that has been chosen",
    "description": "A file the user has chosen",
    "type": "file",
    "value": ""
},