今回は ActiveX に 安全であること を示す実装を行うことで、IEの 警告表示 を回避してみる。 ちなみに、実装は C# (自分が分かる範囲だからという軽い理由…)。
自分が知る限り、ActiveX の 警告回避 は以下のどれかでなかろうかと…思ってる。 そのうち、今回は「ActiveX に安全マークをつける」方法のうち、「コード上に実装する」方法。
- ActiveXにデジタル署名する
- 一般的な認証局で発行したデジタル署名を利用
- オレオレ認証局で発行したデジタル署名を利用
- ActiveXを登録時に安全マークをつける
さて、前置きが長くなりましたが…これから実装を始めます。
実装はいたって単純で、 「IObjectSafety インターフェース」と「IObjectSafety 実装」をコピペして、「IObjectSafety 実装」を継承するだけ。
さて、その「IObjectSafety インターフェース」と「IObjectSafety 実装」についてを以下に載せます。
IObjectSafety.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | 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 を継承した サンプルコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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 の フォロー」 お願いします!!