― MozillaZine.jp フォーラムは Mozilla 製品に関する情報交換の場です ―



All times are UTC + 9 hours

新しいトピックを投稿する トピックへ返信する  [ 14 件の記事 ] 
作成者 メッセージ
投稿記事Posted: 2007年7月01日(日) 20:15 
オフライン

登録日時: 2007年1月14日(日) 14:24
記事: 138
お住まい: Osaka,Japan
 今日一日かけて MDC、XUL Planet 等のサイトで調べてもわからなかったので質問させてください。

 現在週間天気予報をモードレスダイアログボックスで表示する拡張を WindowsXP 環境下で作っています。
 その拡張の機能の中に、ボタンを押すと Firefox が起動している場合に、新しいタブに気象庁の Web ページを表示するというものがあります。
 ただしこの拡張はモードレスダイアログボックスで作成されるようにしていますので、Firefox 本体を終了させてしまうことができます。
 現在、この拡張はユーザが Firefox をオペレーションミスなどで終了させてしまった場合に、OS のデフォルトブラウザを立ち上げて気象庁のページを表示するように暫定的にコードを書いています。コードは以下の通りです。
コード:
function dispJMA()
{
   try
   {
      var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"].getService(Components.interfaces.nsIWindowMediator);
      var mainWindow = wm.getMostRecentWindow("navigator:browser");
      mainWindow.getBrowser().addTab('http://www.jma.go.jp/');
   } catch(e)
   {
      var tempServ = Components.classes["@mozilla.org/process/environment;1"].getService(Components.interfaces.nsIEnvironment);
      var strWinDir = tempServ.get('windir');
      var strCommand = strWinDir + "\\system32\\rundll32.exe";

      var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
      file.initWithPath(strCommand);

      var process =  Components.classes["@mozilla.org/process/util;1"].createInstance(Components.interfaces.nsIProcess);
      process.init(file);

      var args = ["url.dll,OpenURL", "http://www.jma.go.jp/"];
      process.run(false, args, args.length);
   }
}


 見てわかる通り、完全に Windows の環境変数と "rundll32.exe" と "url.dll" に依存したコードになっており、WindowsXP、Windows2000 でないと動作しないようになってしまっています。

 これをマルチプラットフォーム化するために Firefox の起動パスを JavaScript で取得する方法を探しています。おそらく OS の機能に依存することから XPCOM インターフェースを調べればわかるんじゃないかと悪戦苦闘していたのですが、どうしてもその方法が見つかりません。

 どなたか Firefox の起動パスを取得する方法をご存じの方がいらっしゃったらご教示願えないでしょうか。


通報する
ページトップ
 プロフィール  
引用付きで返信する  
投稿記事Posted: 2007年7月02日(月) 01:03 
オフライン

登録日時: 2007年7月01日(日) 23:02
記事: 23
お住まい: 千葉
う~ん、
引用:
Firefox の起動パスを取得したい
引用:
OS のデフォルトブラウザを立ち上げて
は違うような...

デフォルトのブラウザなら以下
コード:
const Cc = Components.classes;
const Ci = Components.interfaces;
var urlSpec = 'http://www.example.com/';
var url = Cc['@mozilla.org/network/standard-url;1'].createInstance(Ci.nsIStandardURL);
url.init(url.URLTYPE_STANDARD, 80, urlSpec, null, null);
var uri = url.QueryInterface(Ci.nsIURI);
var extProtService = Cc['@mozilla.org/uriloader/external-protocol-service;1'].getService(Ci.nsIExternalProtocolService);
extProtService.loadUrl( uri );

たぶん動くと思いますが、私はWindows以外のOSでやってみた事がないので保障できないです :-P
Thunderbird なら messenger.launchExternalURL() があるのに...、Firefoxだと微妙に面倒ですね。


実行ファイルなら以下のようにすれば、Firefoxの実行ファイルが置かれているディレクトリを得る事ができます。ですが、これだと実行ファイル名がOSによって違うので微妙ですね。
コード:
var properties = Cc['@mozilla.org/file/directory_service;1'].getService(Ci.nsIProperties);
var file = properties.get('CurProcD', Ci.nsILocalFile);


通報する
ページトップ
 プロフィール  
引用付きで返信する  
投稿記事Posted: 2007年7月02日(月) 17:14 
オフライン

登録日時: 2007年1月14日(日) 14:24
記事: 138
お住まい: Osaka,Japan
teramako さんが書きました:
実行ファイルなら以下のようにすれば、Firefoxの実行ファイルが置かれているディレクトリを得る事ができます。ですが、これだと実行ファイル名がOSによって違うので微妙ですね。
コード:
var properties = Cc['@mozilla.org/file/directory_service;1'].getService(Ci.nsIProperties);
var file = properties.get('CurProcD', Ci.nsILocalFile);


 teramako さん、ご教示ありがとうございました。おかげさまでインストールディレクトリを取得して Windows 環境で Firefox を起動するコードまでを書くことができました。

 それで更に linux ユーザ、Mac ユーザの方に質問があります。
 上記コードを参考に更に net で調べ、Windows、Mac、linux に対応できるように以下のようにコードを書いています。
コード:
      var   strOs = navigator.userAgent.toUpperCase();
      var   strFirefoxFullPath;
      if (strOs.indexOf("WIN")>=0) {
         strFirefoxFullPath = strInstallPath + '\\firefox.exe';
      } else if (strOs.indexOf("MAC")>=0) {
         strFirefoxFullPath = strInstallPath + '/firefox.app';
      } else if (strOs.indexOf("X11")>=0) {
         strFirefoxFullPath = strInstallPath + '/firefox';
      }
      file.initWithPath(strFirefoxFullPath);

 Mac OS でのパス表記のディスクリプタが "/" で良いのか、また実行ファイル名が "forefox.app" で本当にあっているのか、更に linux 環境での実行ファイル名が "firefox" で本当に良いのかどなたかご教示いただけないでしょうか。


通報する
ページトップ
 プロフィール  
引用付きで返信する  
 記事の件名:
投稿記事Posted: 2007年7月04日(水) 01:00 
オフライン

登録日時: 2007年7月01日(日) 23:02
記事: 23
お住まい: 千葉
引用:
Mac OS でのパス表記のディスクリプタが "/" で良いのか

nsILocalFileのappendメソッドを使った方が良いかと思います。OSを気にしなくても良きに計らってくれるので。
コード:
var properties = Cc['@mozilla.org/file/directory_service;1'].getService(Ci.nsIProperties);
var firefoxFile = properties.get('CurProcD', Ci.nsILocalFile);
var strOs = navigator.userAgent.toUpperCase();
if (strOs.indexOf("WIN")>=0) {
  firefoxFile.append('firefox.exe');
} else if (strOs.indexOf("MAC")>=0) {
  firefoxFile.append('firefox.app');
} else if (strOs.indexOf("X11")>=0)
  firefoxFile.append('firefox');
}
// firefoxFile.path でフルパスを得られる


あと、今更で申し訳ないですが、Code snippets:File I/O - MDCを見ていたら、
引用:
CurProcD (通常) インストールされたディレクトリ
となっているので、もしかするとインストールディレクトリを得る事が出来ないことがあるかもしれません。


通報する
ページトップ
 プロフィール  
引用付きで返信する  
 記事の件名:
投稿記事Posted: 2007年7月04日(水) 09:22 
オフライン

登録日時: 2007年1月14日(日) 14:24
記事: 138
お住まい: Osaka,Japan
 teramako さん、重ね重ねありがとうございます。

teramako さんが書きました:
引用:
Mac OS でのパス表記のディスクリプタが "/" で良いのか

nsILocalFileのappendメソッドを使った方が良いかと思います。OSを気にしなくても良きに計らってくれるので。

 MDC に記載されていた "descendent" のニュアンスがよくわからなかったのですが、つまり nsILocalFileのappend メソッドは file.path に append(string) の "string" をターミネータを含めてアペンドするということなんですね。ご教示ありがとうございました。

teramako さんが書きました:
あと、今更で申し訳ないですが、Code snippets:File I/O - MDCを見ていたら、
引用:
CurProcD (通常) インストールされたディレクトリ
となっているので、もしかするとインストールディレクトリを得る事が出来ないことがあるかもしれません。

 実はこの点、私も若干不安がありnsIDirectoryServiceProvider:getFileを参照したところ、C での define として NS_OS_CURRENT_PROCESS_DIR と記載されていたので、とりあえずインストールディレクトリが返ってくるものと判断しています。"usually" とあるのはちょっと謎ですね。このあたりは最終的には C のコードを追いかけないとダメなのかなぁ、と思っています ( でもそこまで時間はないなぁ~ )。

 teramako さん、ありがとうございました。これでなんとか拡張らしい拡張、つまり Firefox や他の拡張がそうであるように、マルチプラットフォームの拡張にできそうです。心から感謝します。

付記:
 ここに書いても仕方がないのですが、今回初めて Firefox 用の拡張を作っているのですが、XPCOM をダイレクトにコールするのではなくて、クラスライブラリのようなラッパーがあった方が、拡張を作る際に便利だと思いました。それとチュートリアルがもうちょっと充実するといいかなぁ、とも思いました。リファレンスの参照を中心に拡張を作成するのは結構大変です。Firefox3 ではラッパーが用意される予定と聞き及んでいるので、ちょっと期待しています。


通報する
ページトップ
 プロフィール  
引用付きで返信する  
 記事の件名: ていうか
投稿記事Posted: 2007年8月08日(水) 23:02 
オフライン
Moderator

登録日時: 2007年5月03日(木) 01:11
記事: 92
お住まい: 東京
単にFirefoxのブラウザウィンドウを開き直すだけではだめなんでしょうか?

コード:
window.openDialog('chrome://browser/content/browser.xul', '_blank', 'chrome,all,dialog=no', 'http://www.example.com/');


通報する
ページトップ
 プロフィール  
引用付きで返信する  
投稿記事Posted: 2007年8月16日(木) 11:28 
オフライン
Administrator

登録日時: 2006年11月11日(土) 08:10
記事: 308
今更ですが、折角なのでドキュメンテーションの意味を込めて。
teramako さんが書きました:
nsILocalFileのappendメソッドを使った方が良いかと思います。OSを気にしなくても良きに計らってくれるので。
コード:
var properties = Cc['@mozilla.org/file/directory_service;1'].getService(Ci.nsIProperties);
var firefoxFile = properties.get('CurProcD', Ci.nsILocalFile);
var strOs = navigator.userAgent.toUpperCase();
if (strOs.indexOf("WIN")>=0) {
  firefoxFile.append('firefox.exe');
} else if (strOs.indexOf("MAC")>=0) {
  firefoxFile.append('firefox.app');
} else if (strOs.indexOf("X11")>=0)
  firefoxFile.append('firefox');
}
// firefoxFile.path でフルパスを得られる

Mac の場合についてですが、(properties.get('CurProcD', Ci.nsILocalFile)).path は "/Applications/Firefox 2.0.app/Contents/MacOS" となっていますので、これに append する Firefox 実行ファイル名は *.app ではなく firefox です。
コード:
...
} else if (strOs.indexOf("MAC")>=0) {
  firefoxFile.append('firefox');
} ...

が正しいかと思います。


通報する
ページトップ
 プロフィール  
引用付きで返信する  
投稿記事Posted: 2008年9月25日(木) 21:51 
オフライン

登録日時: 2007年1月14日(日) 14:24
記事: 138
お住まい: Osaka,Japan
 かなり昔の話を持ち出してきてすみません。
teramakoさん さんが書きました:
デフォルトのブラウザなら以下
コード:
const Cc = Components.classes;
const Ci = Components.interfaces;
var urlSpec = 'http://www.example.com/';
var url = Cc['@mozilla.org/network/standard-url;1'].createInstance(Ci.nsIStandardURL);
url.init(url.URLTYPE_STANDARD, 80, urlSpec, null, null);
var uri = url.QueryInterface(Ci.nsIURI);
var extProtService = Cc['@mozilla.org/uriloader/external-protocol-service;1'].getService(Ci.nsIExternalProtocolService);
extProtService.loadUrl( uri );


の "nsIStandardURL" の利用ですが、現在の MDC では "Warning: The content of this article may be out of date." となっています。現在 "nsIStandardURL" に代わるインターフェースがあるのでしょうか?


通報する
ページトップ
 プロフィール  
引用付きで返信する  
投稿記事Posted: 2008年9月27日(土) 22:58 
オフライン
Moderator

登録日時: 2006年10月29日(日) 21:56
記事: 472
mitsugu さんが書きました:
の "nsIStandardURL" の利用ですが、現在の MDC では "Warning: The content of this article may be out of date." となっています。現在 "nsIStandardURL" に代わるインターフェースがあるのでしょうか?
話の流れを読んでいないのですが、見た感じ、nsIURI が得られれば良いのでしょうか。
そうだとすると、nsIIOService の newURI メソッドを使えば良いと思います。


通報する
ページトップ
 プロフィール  
引用付きで返信する  
投稿記事Posted: 2008年10月01日(水) 15:31 
オフライン

登録日時: 2007年1月14日(日) 14:24
記事: 138
お住まい: Osaka,Japan
 すいません。現在、実はこのスレッドを立てたときの拡張を XULRunner アプリケーションに改造しています。すると、MDC の "nsIStandardURL" を調べてみると、先に書いた "Warning: The content of this article may be out of date." と記載されていたんです。
 恥ずかしい話なんですが、それで
コード:
const Cc = Components.classes;
const Ci = Components.interfaces;
var urlSpec = 'http://www.example.com/';
var url = Cc['@mozilla.org/network/standard-url;1'].createInstance(Ci.nsIStandardURL);
url.init(url.URLTYPE_STANDARD, 80, urlSpec, null, null);
var uri = url.QueryInterface(Ci.nsIURI);
var extProtService = Cc['@mozilla.org/uriloader/external-protocol-service;1'].getService(Ci.nsIExternalProtocolService);
extProtService.loadUrl( uri );

をどう書き換えたら良いのか MDC を読んでも分からず、途方に暮れていたのです。


通報する
ページトップ
 プロフィール  
引用付きで返信する  
投稿記事Posted: 2008年10月02日(木) 11:10 
オフライン
Moderator

登録日時: 2007年5月03日(木) 01:11
記事: 92
お住まい: 東京
自分はマニュアルを見てもよく分からず、実例をたくさん見てやっと理解できるタイプの人間なのですが、こういう場合に自分がどうやっているかという例をご紹介します。参考になれば幸いです。

まず、loadUrlメソッドの定義を調べます。ここではnsIExternalProtocolServiceインターフェースのメソッドと思われるので、nsIExternalProtocolServiceインターフェースのIDL定義を探してみました。
http://mxr.mozilla.org/mozilla1.8/sourc ... ervice.idl (←これはFirefox 2.0.0.x系のブランチですが、Trunkでも3.0.x系でも内容は変わっていなかったのでとりあえずこちらを貼っておきます)
これを見ると、このメソッドの引数はnsIURI型となっています。

nsIURI型のオブジェクトの作り方としては、あさんが書かれているとおり、nsIIOServiceのnewURIメソッドを使う方法が一般的です。どうやってオブジェクトを作ればいいのか分からない(実際のやり方が分からない)、という場合には、MXR( http://mxr.mozilla.org/ )の文字列検索でメソッド名やインターフェース名を検索してみると、Firefox等の中での実際の使われ方を見ることができます。


通報する
ページトップ
 プロフィール  
引用付きで返信する  
投稿記事Posted: 2008年10月02日(木) 11:20 
オフライン

登録日時: 2007年1月14日(日) 14:24
記事: 138
お住まい: Osaka,Japan
 piro さん、ありがとうございます。こういった情報を集める手順を教えていただけると、大変助かります。さっそく調べてみます。


通報する
ページトップ
 プロフィール  
引用付きで返信する  
投稿記事Posted: 2008年10月02日(木) 11:40 
オフライン

登録日時: 2007年1月14日(日) 14:24
記事: 138
お住まい: Osaka,Japan
 あさん、piro さん、おかげさまで、コードがすごくシンプルになりました。本当に有難うございました。


通報する
ページトップ
 プロフィール  
引用付きで返信する  
 記事の件名: コード書いときます
投稿記事Posted: 2008年10月04日(土) 09:31 
オフライン

登録日時: 2007年1月14日(日) 14:24
記事: 138
お住まい: Osaka,Japan
 せっかくなので、コードを置いておきます。
 nsIIOService のおかげでわずか 4 ステップですむようになりました (*⌒∇⌒*)
コード:
   var ioservice = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);
   var uriToOpen = ioservice.newURI("http://www.jma.go.jp/jma/index.html", null, null);
   var extProtService = Components.classes["@mozilla.org/uriloader/external-protocol-service;1"].getService(Components.interfaces.nsIExternalProtocolService);
   extProtService.loadUrl( uriToOpen,null );


通報する
ページトップ
 プロフィール  
引用付きで返信する  
期間内表示:  ソート  
新しいトピックを投稿する トピックへ返信する  [ 14 件の記事 ] 

All times are UTC + 9 hours


オンラインデータ

このフォーラムを閲覧中のユーザー: なし & ゲスト[18人]


トピック投稿:  可
返信投稿:  可
記事編集: 不可
記事削除: 不可
ファイル添付: 不可

検索:
ページ移動:  
Powered by MozillaZine.jp® Forum Software © phpBB Group , Almsamim WYSIWYG
Japanese translation principally by ocean