扩展中的Firefox命令行参数

时间:2016-04-28 23:23:35

标签: firefox firefox-addon firefox-addon-sdk

我试图在我的扩展程序中获取firefox命令行的参数:

'firefox.exe -viewapp url -another-command -blablala:somedata'

here我找到了一个例子

但是我不知道如何在浏览器首次启动时获得所有参数。 我需要在Web控制台中显示如下内容:

console.log(commandLine.arguments)
// -viewapp url -another-command -blablala:somedata

请帮忙

2 个答案:

答案 0 :(得分:4)

我看到你只想查看它启动的命令行参数。我知道一个js-ctypes解决方案。这将要求您为不同的平台编码。这是一个开始,它可以获得关于windows和mac的参数。我还没有做linux部分:

Cu.import('resource://gre/modules/osfile.jsm');
Cu.import('resource://gre/modules/ctypes.jsm');

var lib 
var osname = OS.Constants.Sys.Name.toLowerCase();
if (osname.indexOf('win') === 0) {
    // windows
    lib = ctypes.open('kernel32');
    var GetCommandLineW = lib.declare('GetCommandLineW', ctypes.winapi_abi,  ctypes.jschar.ptr);
    var rez = GetCommandLineW();
    console.log('rez:', rez.readString());
} else if (osname == 'darwin') {
    // mac

    lib = ctypes.open(ctypes.libraryName('objc'));

    // BASIC TYPES
    var BOOL = ctypes.signed_char;
    var NSUINTEGER = ctypes.unsigned_long;

    // COMMON FUNCTIONS
    var objc_getClass = lib.declare('objc_getClass', ctypes.default_abi, ctypes.voidptr_t, ctypes.char.ptr);
    var objc_msgSend = lib.declare('objc_msgSend', ctypes.default_abi, ctypes.voidptr_t, ctypes.voidptr_t, ctypes.voidptr_t, '...');
    var sel_registerName = lib.declare('sel_registerName', ctypes.default_abi, ctypes.voidptr_t, ctypes.char.ptr);

    // current_application = [NSRunningApplication currentApplciation];
    var NSProcessInfo = objc_getClass('NSProcessInfo');
    var processInfo = sel_registerName('processInfo');
    var process_info = objc_msgSend(NSProcessInfo, processInfo);

    // bundle_identifier = [current_application bundleIdentifier]
    var arguments = sel_registerName('arguments');
    var args = objc_msgSend(process_info, arguments);


    var count = sel_registerName('count');
    var _count = objc_msgSend(args, count);
    console.info('_count:', _count, _count.toString(), uneval(_count), parseInt(_count));

    // make it into a js number
    _count = parseInt(ctypes.cast(_count, NSUINTEGER).value); 
    console.log('_count:', _count);

    var objectAtIndex = sel_registerName('objectAtIndex:'); // used in for loop
    var UTF8String = sel_registerName('UTF8String'); // used in for loop

    for (var i=0; i<_count; i++) {
        var arg = objc_msgSend(args, objectAtIndex, NSUINTEGER(i)); // must wrap `i` in NSUINTEGER as its variadic, you have to specify the type. this is specific to js-ctypes         
        var argString = ctypes.cast(objc_msgSend(arg, UTF8String), ctypes.char.ptr);
        console.log('arg "' + i + '":', argString.readStringReplaceMalformed(), 'arg:', arg, arg.toString(), uneval(arg));
    }

} else {
    // *nix

    // todo
    // per - http://stackoverflow.com/a/821889/1828637
    var libcPaths = ['libc.so', 'libc.so.7', 'libc.so.61.0', 'libc.so.6', 'libc.so.0.1', 'libc.dylib'];
    for (var i=0; i<libcPaths.length; i++) {
        try {
            lib = ctypes.open(libcPaths[i]);
            break;
        } catch(ignore) {}
    }
    if (!lib) {
        throw new Error('failed to find libc on this system');
    }

    var popen = lib.declare('popen', ctypes.default_abi, ctypes.voidptr_t, ctypes.char.ptr, ctypes.char.ptr);
    var fread = lib.declare('fread', ctypes.default_abi, ctypes.size_t, ctypes.voidptr_t, ctypes.size_t, ctypes.size_t, ctypes.voidptr_t);
    var feof = lib.declare('feof', ctypes.default_abi, ctypes.int, ctypes.voidptr_t);
    var pclose = lib.declare('pclose', ctypes.default_abi, ctypes.int, ctypes.voidptr_t);
    var getpid = lib.declare('getpid', ctypes.default_abi, ctypes.int32_t);

    // ps -fp 2540
    var pid = getpid();
    var file = popen('ps -ww -fp' + pid, 'r');

    var buf = ctypes.char.array(100)();
    var jsbuf = [];
    var reachedEof = false;
    while (!reachedEof) {
        var cnt = fread(buf, 1, buf.length * buf.constructor.elementType.size, file);
        cnt = parseInt(cnt);
        if (cnt > 0) {
            jsbuf.push(buf.readString().substring(0, cnt));
        }
        reachedEof = feof(file);
    }

    var closeit = pclose(file);
    console.log('closeit:', closeit);

    console.log('jsbuf:', jsbuf.join(''));
}

lib.close();

答案 1 :(得分:3)

这是一个非常简单的插件:

https://github.com/Noitidart/Restore--remote/blob/master/bootstrap.js

这个插件是一个bootstrap(所以不重启 - 这很好)插件。因此,如果您使用SDK,则必须使用低级别的东西。它也不需要像你链接到的MDN那样的chrome.manifest文件。

以下是市场上的插件 - https://addons.mozilla.org/en-US/firefox/addon/restore-remote/

以下是代码:

const Cc = Components.classes;
const Ci = Components.interfaces;
const Cm = Components.manager;
const Cu = Components.utils;
const Cr = Components.results;

Cm.QueryInterface(Ci.nsIComponentRegistrar);

Cu.import('resource://gre/modules/XPCOMUtils.jsm');
Cu.import('resource://gre/modules/Services.jsm');
Cu.import('resource://gre/modules/Preferences.jsm');

function RemoteCommandLine(target, url, cl) {
  this._target = target;
  this._url = url;
  this._cl = cl;
}

RemoteCommandLine.prototype = {
  get preventDefault() {
    return this._cl.preventDefault;
  }, 
  set preventDefault(value) {
    this._cl.preventDefault = value;
  },
  handleFlag: function(flag, caseSensitive) {
    return false;
  },
  handleFlagWithParam: function(flag, caseSensitive) {
    if (!(flag == 'new-tab' && this._target == Ci.nsIBrowserDOMWindow.OPEN_NEWTAB) &&
        !(flag == 'new-window' && this._target == Ci.nsIBrowserDOMWindow.OPEN_NEWWINDOW))
      return null;
    var url = this._url;
    this._url = null;
    return url
  },
  resolveURI: function(url) {
    return this._cl.resolveURI(url);
  },
};

function Remote() {}

Remote.prototype = {
  QueryInterface: XPCOMUtils.generateQI([Ci.nsICommandLineHandler]),
  classDescription: 'remote',
  classID: Components.ID('{1280e159-cac2-4188-af5a-e6089527b7b8}'),
  contractID: '@mozilla.org/commandlinehandler/general-startup;1?type=remote',

  handle: function(cmdLine)
  {
    try {
      var remoteCommand = cmdLine.handleFlagWithParam("remote", true);
    }
    catch (e) {
      throw Cr.NS_ERROR_ABORT;
    }

    if (remoteCommand != null) {
      try {
        var a = /^\s*(\w+)\(([^\)]*)\)\s*$/.exec(remoteCommand);
        var remoteVerb;
        if (a) {
          remoteVerb = a[1].toLowerCase();
          var remoteParams = [];
          var sepIndex = a[2].lastIndexOf(",");
          if (sepIndex == -1)
            remoteParams[0] = a[2];
          else {
            remoteParams[0] = a[2].substring(0, sepIndex);
            remoteParams[1] = a[2].substring(sepIndex + 1);
          }
        }

        switch (remoteVerb) {
        case "openurl":
        case "openfile":
          // openURL(<url>)
          // openURL(<url>,new-window)
          // openURL(<url>,new-tab)

          // First param is the URL, second param (if present) is the "target"
          // (tab, window)
          var url = remoteParams[0];
          var target = Ci.nsIBrowserDOMWindow.OPEN_DEFAULTWINDOW;
          if (remoteParams[1]) {
            var targetParam = remoteParams[1].toLowerCase()
                                             .replace(/^\s*|\s*$/g, "");
            if (targetParam == "new-tab")
              target = Ci.nsIBrowserDOMWindow.OPEN_NEWTAB;
            else if (targetParam == "new-window")
              target = Ci.nsIBrowserDOMWindow.OPEN_NEWWINDOW;
            else {
              // The "target" param isn't one of our supported values, so
              // assume it's part of a URL that contains commas.
              url += "," + remoteParams[1];
            }
          }

          if (target == Ci.nsIBrowserDOMWindow.OPEN_DEFAULTWINDOW) {
            target = Preferences.get('browser.link.open_newwindow',
                                     Ci.nsIBrowserDOMWindow.OPEN_NEWTAB);
          }

          var clh = Cc['@mozilla.org/browser/clh;1'].getService(Ci.nsICommandLineHandler);
          clh.handle(new RemoteCommandLine(target, url, cmdLine));
          break;


        case "ping":
          break;
        default:
          // Somebody sent us a remote command we don't know how to process:
          // just abort.
          throw "Unknown remote command.";
        }

        cmdLine.preventDefault = true;
      }
      catch (e) {
        Components.utils.reportError(e);
        // If we had a -remote flag but failed to process it, throw
        // NS_ERROR_ABORT so that the xremote code knows to return a failure
        // back to the handling code.
        throw Cr.NS_ERROR_ABORT;
      }
    }
  },
};

const RemoteFactory = XPCOMUtils.generateNSGetFactory([Remote])(Remote.prototype.classID);

function startup(aData, aReason) {
  Cm.registerFactory(Remote.prototype.classID,
                     Remote.prototype.classDescription,
                     Remote.prototype.contractID,
                     RemoteFactory);
  var catman = Cc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager);
  catman.addCategoryEntry('command-line-handler', 'l-remote', Remote.prototype.contractID, false, true);
}

function shutdown(aData, aReason) {
  var catman = Cc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager);
  catman.deleteCategoryEntry('command-line-handler', 'l-remote', false);
  Cm.unregisterFactory(Remote.prototype.classID, RemoteFactory);
}