今回は ActiveX に 安全であること を示す実装を行うことで、IEの 警告表示 を回避してみる。 ちなみに、実装は C# (自分が分かる範囲だからという軽い理由…)。
自分が知る限り、ActiveX の 警告回避 は以下のどれかでなかろうかと…思ってる。 そのうち、今回は「ActiveX に安全マークをつける」方法のうち、「コード上に実装する」方法。
- 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" などは任意に読み替え、書き換えてください。
今回、参考にさせていただいた情報源は以下の通りです。
- Exposing COM interfaces of a .NET class library for Late Binding
- Building COM Objects in C#
- Safe Initialization and Scripting for ActiveX Controls
- IObjectSafety Interface
- IObjectSafety マーク ATL コントロール セーフを初期化する方法
- アクティブ デバッグの ATL ActiveX スクリプト エンジンを実装する方法
最後に… このブログに興味を持っていただけた方は、 ぜひ 「Facebookページ に いいね!」または 「Twitter の フォロー」 お願いします!!