IEコンテキストメニューからの.NETアセンブリ呼び出し

先日から続いているデータベース関連の続き。ネットを巡回中に面白いページを見つけるとお気に入りに登録したりしますが、登録名はページのタイトルだったりするので、なにを見つけて登録したのか分からなくなってしまいます。もちろん、きちんとタイトルを付けたり、分類すればよいのですが、整理整頓の苦手な私としてはもう少しお手軽にしたいところ。例えば、ブラウザ上でテキストを選択し、ポップアップメニューから登録を行うと、選択テキストとそのページのURLがデータベースに登録されるようなものがあれば便利そうな気が。さて、ここで問題は

  1. IEコンテキストメニューへの登録方法
  2. IEから.NETアセンブリの呼び出し方法

この2つ。

1つめは、で解決。2つ目は、COMなら呼び出せるのでCCW(COM Callable Wrapper)を使えば良さそうです。CCWを使ったことがないので、ちょっと実験です。

using System;
using System.Runtime.InteropServices;

namespace CCWCalc
{
  // デュアルインタフェースの生成
  [ClassInterface(ClassInterfaceType.AutoDual)]
  public class Calc
  {
    // パブリックコンストラクタが必要?
    public Calc() {}
    public int Add(int x, int y) {
      return x + y;
    }

    public int Subtract(int x, int y) {
      return x - y;
    }
  }
}

こんなクラスを含んだ.NETアセンブリを作成します。COMとして動作するにはレジストリ登録が必要なので、次のコマンドを実行します。(CCWCalc.dllが作成したアセンブリ)

> regasm CCWCalc.dll

登録が出来たら、COM/OLE Object ViewerなどでCLSID(ここでは98D0F96D-0EE3-36A3-9882-0ED26464E848)を調べておきます。これで、JavaScriptなどから呼び出せるようになりました。

<html>
<head>
<script language="JavaScript" defer>
<!--
function Define()
{
  var ans;
  ans = calc.Add(1, 2);
  alert(ans);
}
 -->
</script>
</head>

<body Language="JavaScript" onLoad="Define()">
<object ID="calc" CLASSID="CLSID:98D0F96D-0EE3-36A3-9882-0ED26464E848"></object>
</body>
</html>

こんな風に呼び出せます。上記をCCWCalc.htmlとか名前を付けて保存。これを、1の方法でコンテキストメニューから呼び出すようにします。これで、IEコンテキストメニューから実行すると計算結果の3がメッセージボックスに表示されます。

※注意 .NETアセンブリは実行モジュールと同じディレクトリに置くか、GACに登録しなければなりません。

技術検証は出来たので、後は選択されたテキストとURLをMySQLに放り込むアセンブリを作成すれば完成かな。


(追記) で、完成。

<html>
<head>
<script language="JavaScript" defer>
<!--
function Define()
{
  // MySQLの接続文字列
  var dbstr='Data Source=localhost;Database=mei_db;User Id=user;Password=pass;';
  var parentwin = external.menuArguments;
  var url = parentwin.location.href;
  var doc = parentwin.document;
  var sel = doc.selection;
  var rng = sel.createRange();
  var str = new String(rng.text);
  if(str.length > 0) {
    weblog.ConnectionString=dbstr;
    // URLと選択文字列をセットでDBに登録
    weblog.Register(url, str);
  }
}
 -->
</script>
</head>

<body Language="JavaScript" onLoad="Define()">
    <object ID="weblog" CLASSID="CLSID:97059A1A-D3E6-346C-8A00-B8B63DB636F3"></object>
</body>
</html>

.NETアセンブリはDBへinsertしているだけなので省略。