今回は、Internet Explorer 上で動作する アドオン の開発を C# で実装してみます。
アドオンはページ内で ActiveX オブジェクトの生成を行う、または objectタグ を HTML に書き込むことで利用できるものです。 メニューの[ツール]-[アドオンの管理]から、現在利用できるアドオンを確認できます。
※ 本記事の更新履歴を末尾に掲載しています。
本記事 の メニュー
今回は、Internet Explorer 上で動作する アドオン の開発を C# で実装してみます。
アドオンはページ内で ActiveX オブジェクトの生成を行う、または objectタグ を HTML に書き込むことで利用できるものです。 メニューの[ツール]-[アドオンの管理]から、現在利用できるアドオンを確認できます。
※ 本記事の更新履歴を末尾に掲載しています。
本記事 の メニュー
今回は ActiveX に 安全であること を示す実装を行うことで、IEの 警告表示 を回避してみる。 ちなみに、実装は C# (自分が分かる範囲だからという軽い理由…)。
自分が知る限り、ActiveX の 警告回避 は以下のどれかでなかろうかと…思ってる。 そのうち、今回は「ActiveX に安全マークをつける」方法のうち、「コード上に実装する」方法。
さて、前置きが長くなりましたが…これから実装を始めます。
実装はいたって単純で、 「IObjectSafety インターフェース」と「IObjectSafety 実装」をコピペして、「IObjectSafety 実装」を継承するだけ。
さて、その「IObjectSafety インターフェース」と「IObjectSafety 実装」についてを以下に載せます。
IObjectSafety.cs
namespace Sample.ActiveXPlugIn { using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; [ComImport, Guid("CB5BDC81-93C1-11CF-8F20-00805F2CD064")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IObjectSafety { [PreserveSig] uint GetInterfaceSafetyOptions( ref Guid riid, [MarshalAs(UnmanagedType.U4)] ref int pdwSupportedOptions, [MarshalAs(UnmanagedType.U4)] ref int pdwEnabledOptions); [PreserveSig] uint SetInterfaceSafetyOptions( ref Guid riid, [MarshalAs(UnmanagedType.U4)] int dwOptionSetMask, [MarshalAs(UnmanagedType.U4)] int dwEnabledOptions); } }
COM 関係が利用したいので、System.Runtime.InteropServices 名前空間を追加します。
属性をいくつか付けるのですが、COM の実装に合わせるため、GUID "CB5BDC81-93C1-11CF-8F20-00805F2CD064" も含めて、
まったく同じ属性をつけます。
…というか、"CB5BDC81-93C1-11CF-8F20-00805F2CD064" が安全マークを示すインターフェースの実態のようです。
IObjectSafetyTLB.cs
namespace Sample.ActiveXPlugIn { using System; using System.Collections.Generic; using System.Linq; using System.Text; public class IObjectSafetyTLB : IObjectSafety { // --------------------------------------------------- // 定数 // --------------------------------------------------- private const int INTERFACESAFE_FOR_UNTRUSTED_CALLER = 0x00000001; private const int INTERFACESAFE_FOR_UNTRUSTED_DATA = 0x00000002; private const int INTERFACE_USES_DISPEX = 0x00000004; private const int INTERFACE_USES_SECURITY_MANAGER = 0x00000008; private const uint S_OK = 0x00000000; private const uint E_NOINTERFACE = 0x80004002; private const uint E_FAIL = 0x80004005; // --------------------------------------------------- // メンバ関数 // --------------------------------------------------- public uint GetInterfaceSafetyOptions(ref Guid riid, ref int pdwSupportedOptions, ref int pdwEnabledOptions) { return S_OK; } public uint SetInterfaceSafetyOptions(ref Guid riid, int dwOptionSetMask, int dwEnabledOptions) { return S_OK; } } }
IObjectSafety インターフェースを実装する実態クラスになります。
本来は、引き渡された参照データ(pdwSupportedOptions, pdwEnabledOptionsとか…)を参考にイロイロこねくり回して、
S_OK, E_NOINTERFACE, E_FAIL のどれかを返すようです。
が、面倒くさいのとよく分からないとを理由に無条件に S_OK として使わせてもらいます。
ちなみに、その他の定数周りはインターネットから拾ってきたので、怪しいです…。。
あとは、IObjectSafetyTLB クラス を plugin にしたいクラスに対して継承させてあげればOK。
IObjextSafetyTLB を継承した サンプルコード
namespace Sample.ActiveXPlugIn { using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Windows.Forms; [Guid("YOURGUID-0000-0000-0000-000000000000")] [ComSourceInterfaces(typeof(IMyFormEvent))] [ClassInterface(ClassInterfaceType.None)] [ProgId("Sample.ActiveXPlugIn.MyForm")] public class MyForm : IObjectSafetyTLB, IMyFormMethod { // IE プラグイン の実装。 } }
さすがにとは思いますが… プラグインのGUID"YOURGUID-0000-0000-0000-000000000000"や名前空間"Sample.ActiveXPlugIn"、 プラグイン実態クラス名"MyForm"、プラグインインターフェース名"IMyFormEvent", "IMyFormMethod" などは任意に読み替え、書き換えてください。
今回、参考にさせていただいた情報源は以下の通りです。
ActiveX を警告なしに実行する方法はたぶん次の通り。
"ActiveX に安全マーク をつけて 警告回避" では回避できないことがあるようだったので、 別の方法(レジストリに"事前承認済み"を書き込む方法)を調べてみた。
想定している環境は次の通り。ただ、実際は Internet Explorer 7 以上が対象になるみたい。
上記環境において、ActiveX を "承認済み" とするためには、インストール時に次のようなレジストリ登録を行う。
32bit OS の場合
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Ext\PreApproved\{YOURGUID-0000-0000-0000-000000000000}
64bit OS の場合
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Ext\PreApproved\{YOURGUID-0000-0000-0000-000000000000}
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Ext\PreApproved\{YOURGUID-0000-0000-0000-000000000000}
※"YOURGUID-0000-0000-0000-000000000000"は任意に読み替えてください。
64bit の Windows に付属する Internet Explorer を何も考えずに起動すると、32bit IE が起動してしまう。
32bit で動作するアプリ は HKLM\SOFTWARE\Wow6432Node 以下を読みに行くので、32bit 用のレジストリを登録していないと何度やっても警告はでてしまう。
やられたー…と、思ったけど、64bit も 32bit も動かそうとしてくれたわけだから仕方ないとあきらめるか…
まだ、もう少し不十分な感じがいなめないけど…このあたりまでで。。
参考は以下のサイト
IEでActiveXをセキュリティ警告を出さずに実行するためには次のいずれかを行うのが一般的と思うんだけど…
今回は"ActiveX を登録時、レジストリに安全マークをつける"方法で警告回避。
(備忘録的書き込みなのでウソがあるかもしれません。。あしからずご了承を…)
「どうせ、ActiveXのインストールが必要なので、そのときついでにレジストリ登録もやっちゃえ」という発想。
実際は、コード上に実装する方法がうまくいかなかったので、このやり方にした。。
書き込むレジストリは以下の通り。
HKEY_CLASSES_ROOT\Component Categories\{7DD95801-9882-11CF-9FA9-00AA006C42C4}
HKEY_CLASSES_ROOT\Component Categories\{7DD95802-9882-11CF-9FA9-00AA006C42C4}
HKEY_CLASSES_ROOT\CLSID\{YOURGUID-0000-0000-0000-000000000000}\Implemented Categories\{7DD95801-9882-11CF-9FA9-00AA006C42C4}
HKEY_CLASSES_ROOT\CLSID\{YOURGUID-0000-0000-0000-000000000000}\Implemented Categories\{7DD95802-9882-11CF-9FA9-00AA006C42C4}
※"YOURGUID-0000-0000-0000-000000000000"は任意に読み替えてください。
要するに、次の2つのレジストリキーが存在すると、 該当するコンポーネントは"安全"と認識されるらしい。
参考サイトは以下。