2

我目前正在构建一个附加组件,我想在第一次运行时执行特定代码。更具体地说,我想单击我的添加按钮,浏览我的文件并选择一个可执行文件。这个浏览过程应该只在第一次运行时完成,因为我希望我的按钮“记住”在第一次运行后打开这个特定文件。

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

但是,这是已归档的内容,当我尝试此操作时,我的代码没有成功并得到:“消息:ReferenceError:jetpack 未定义”。

在这一点上,我很困惑,因为我已经查看了一些与我想要的相关的问题,但我无法弄清楚如何在我的插件中实现这个急需的功能。有人可以指出我正确的方向或提供一些有效的代码示例吗?

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

4

1 回答 1

4

首次运行代码的一般情况是您使用存储在首选项中的某种标志来指示您是否已运行代码。首选项是 Firefox 中用于在应用程序重新启动时存储简单数据的内容。标志可以是多种类型中的任何一种(字符串、数字、布尔值等)。你只需要有一个值,你可以测试看看你是否已经运行了你的第一次运行代码。这种情况的一般情况在 MDN 的附录 B:安装和卸载脚本中进行了讨论,但该页面不是特定于 SDK 的。当您的附加代码开始运行时,您将测试该标志是否表明您已经运行了您的首次运行代码。如果标志表明您尚未运行第一次运行的代码,则运行该代码并设置标志以表明它已运行。您可以稍微修改一下以使代码仅在升级到新版本时运行(只是另一个标志)等。

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

在这种情况下,如果在我们尝试打开文件时发现存储的文件不存在(例如,用户删除/移动了文件),我们也会运行代码来浏览文件。显然,您还应该有一种方法让用户手动启动文件选择器。幸运的是,当我们声明as时, simple-prefs 系统会为我们解决这个问题。“浏览”按钮将显示在选项对话框中,用户可以使用该按钮手动选择不同的文件。typefile

类似于以下内容:

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": ""
},
于 2015-09-10T16:53:26.197 回答