Mozilla's getting a new look. What do you think? https://mzl.la/brandsurvey

CommandLine

Handling command line arguments with XULRunner

For Multiple Instances Application

XULRunner でアプリケーション固有のコマンドライン引数を取得するのは、一つのインスタンスしか持たないアプリケーションでなければとても簡単です。 nsICommandLine オブジェクトが起動したwindowの引数を最初に渡してくれます:

Example

var cmdLine = window.arguments[0];
cmdLine = cmdLine.QueryInterface(Components.interfaces.nsICommandLine);
alert(cmdLine.handleFlagWithParam("test", false));

For Single Instance Application

もちろん、一つのインスタンスしか持たないアプリケーション (詳細はtoolkit.singletonWindowType をご覧ください)でも、先ほど示したサンプルはアプリケーションの最初の起動時のみ有効です。しかしながら、もし最後のコマンドライン引数を取得したい(例えばファイルを開くなど)のであれば、それを可能とする解決方法はあなた用のcommand line handler を作る事です。

単純なソリューションとしては、observer service を新たな引数が存在する事を通知するオブザーバとする事です。このソリューションを実装する似た方法もしくはよりよい方法としては、特定のハンドラのレジスタかアンレジスタする関数をコマンドラインハンドラサービスとして定義する事です。このアプローチは Songbird で利用されています。

Example

Command Line Handler Component を定義します: components/clh.js

const nsISupports              = Components.interfaces.nsISupports;

const nsICategoryManager       = Components.interfaces.nsICategoryManager;
const nsIComponentRegistrar    = Components.interfaces.nsIComponentRegistrar;
const nsICommandLine           = Components.interfaces.nsICommandLine;
const nsICommandLineHandler    = Components.interfaces.nsICommandLineHandler;
const nsIFactory               = Components.interfaces.nsIFactory;
const nsIModule                = Components.interfaces.nsIModule;

const CLASS_ID = Components.ID("178cfbb6-503c-11dc-8314-0800200c9a66");
const CLASS_NAME = "ApplicationNameCLH";
const CONTRACT_ID = "@example.com/applicationname/clh;1";
const CLD_CATEGORY = "m-applicationname";

var appHandler = {
  /* nsISupports */
  QueryInterface : function clh_QI(aIID)
  {
    if (aIID.equals(nsICommandLineHandler) ||
        aIID.equals(nsIFactory) ||
        aIID.equals(nsISupports))
      return this;

    throw Components.results.NS_ERROR_NO_INTERFACE;
  },

  /* nsICommandLineHandler */
  handle : function clh_handle(aCmdLine)
  {
    var observerService = Components.classes["@mozilla.org/observer-service;1"]
                                    .getService(Components.interfaces.nsIObserverService);
    observerService.notifyObservers(aCmdLine, "commandline-args-changed", null);
  },

  helpInfo : "  -test <value>        A test attribute\n",

  /* nsIFactory */
  createInstance : function mdh_CI(aOuter, aIID)
  {
    if (aOuter != null) {
      throw Components.results.NS_ERROR_NO_AGGREGATION;
    }

    return this.QueryInterface(aIID);
  },

  lockFactory : function mdh_lock(aLock)
  {
    /* no-op */
  }
};

var appHandlerModule = {
  /* nsISupports */
  QueryInterface : function mod_QI(aIID)
  {
    if (aIID.equals(nsIModule) ||
        aIID.equals(nsISupports))
      return this;

    throw Components.results.NS_ERROR_NO_INTERFACE;
  },

  /* nsIModule */
  getClassObject : function mod_gch(aCompMgr, aCID, aIID)
  {
    if (aCID.equals(CLASS_ID))
      return appHandler.QueryInterface(aIID);

    throw components.results.NS_ERROR_FAILURE;
  },

  registerSelf : function mod_regself(aCompMgr, aFileSpec, aLocation, aType)
  {
    var compReg = aCompMgr.QueryInterface(nsIComponentRegistrar);

    compReg.registerFactoryLocation(CLASS_ID, CLASS_NAME, CONTRACT_ID,
                                    aFileSpec, aLocation, aType);

    var catMan = Components.classes["@mozilla.org/categorymanager;1"]
                           .getService(nsICategoryManager);
    catMan.addCategoryEntry("command-line-handler",
                            CLD_CATEGORY, CONTRACT_ID, true, true);
  },

  unregisterSelf : function mod_unreg(aCompMgr, aLocation, aType)
  {
    var compReg = aCompMgr.QueryInterface(nsIComponentRegistrar);
    compReg.unregisterFactoryLocation(CLASS_ID, aLocation);

    var catMan = Components.classes["@mozilla.org/categorymanager;1"]
                           .getService(nsICategoryManager);
    catMan.deleteCategoryEntry("command-line-handler", CLD_CATEGORY);
  },

  canUnload : function (aCompMgr)
  {
    return true;
  }
};

function NSGetModule(aCompMgr, aFileSpec)
{
  return appHandlerModule;
}

引数が変更された時に通知を受け取るオブザーバを作ります: chrome/content/cmdline.js

function CommandLineObserver() {
  this.register();
}
CommandLineObserver.prototype = {
  observe: function(aSubject, aTopic, aData) {
     var cmdLine = aSubject.QueryInterface(Components.interfaces.nsICommandLine);
     var test = cmdLine.handleFlagWithParam("test", false);
     alert("test = " + test + ");
  },

  register: function() {
    var observerService = Components.classes["@mozilla.org/observer-service;1"]
                                    .getService(Components.interfaces.nsIObserverService);
    observerService.addObserver(this, "commandline-args-changed", false);
  },

  unregister: function() {
    var observerService = Components.classes["@mozilla.org/observer-service;1"]
                                    .getService(Components.interfaces.nsIObserverService);
    observerService.removeObserver(this, "commandline-args-changed");
  }
}

var observer = new CommandLineObserver();


// アプリケーションの初回起動時には CommandLineObserver がまだレジストされていないため、
// ここで通知のふりをしてあげます。
var observerService = Components.classes["@mozilla.org/observer-service;1"]
                                 .getService(Components.interfaces.nsIObserverService);
observerService.notifyObservers(window.arguments[0], "commandline-args-changed", null);

addEventListener("unload", observer.unregister, false);

最後に、アプリケーションのWindowにオブザーバへの参照を追加します: chrome/content/window.xul

<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>

<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
        id="main" title="&window.title;" windowtype="xulmine"
        style="width: 300px; height: 350px;"
        persist="screenX screenY width height sizemode">
  <script type="application/x-javascript" src="cmdline.js" />
  ...
</window>

Original Document Information

ドキュメントのタグと貢献者

タグ: 
 このページの貢献者: Btm
 最終更新者: Btm,