6
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Internet Explorer を自作アドオンで拡張する(.NET Framework使用)

Posted at

はじめに

Internet Explorer(インターネットエクスプローラー)はオワコン、かと思いきや、サポート終了は未定1で、サーバーエディションのOSにEdgeがまだ搭載されず、の状況です。
RPA も盛況で自動操作がいろいろできると便利であると思いますので、拡張方法を簡単にまとめてみました。

手順

Visual Studio 2019 で作成する例です。

プロジェクト作成

プロジェクトテンプレートを指定して作成

プロジェクトテンプレートとして、クラスライブラリ (.NET Framework) を選択して作成します。ソリューション名、フレームワークなどは任意です。

image.png

プロジェクトのプロパティでCOM公開設定

プロジェクトのプロパティ「アプリケーション」から「アセンブリ情報」ボタンをクリックして「アセンブリをCOM参照可能にする」へチェックを入れてOKボタンにて保存します。

参照設定

「ソリューションエクスプローラー」の「参照」を右クリックして「参照の追加」を選択し、「COM」からつぎの2つを追加します。このほか、メッセージボックス表示のための System.Windows.Forms アセンブリなども必要に応じて追加します。

  • Microsoft HTML Object (DOM を操作しないなら不要)
  • Microsoft Internet Controls

コーディング

IObjectWithSite インターフェイスをCOM 公開します。

ソリューションエクスプローラーで、ソリューションにインターフェイスを追加し、ファイル名を IObjectWithSite.cs とします。

IObjectWithSite.cs
using System;
using System.Runtime.InteropServices;

namespace SampleIEAddOn
{
    [ComVisible(true),
     InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
     Guid("FC4801A3-2BA9-11CF-A229-00AA003D7352")]

    public interface IObjectWithSite
    {
        [PreserveSig]
        int SetSite([MarshalAs(UnmanagedType.IUnknown)]object site);
        [PreserveSig]
        int GetSite(ref Guid guid, out IntPtr ppvSite);
    }
}

次に、ソリューションエクスプローラーで、自動生成されている Class1.cs の名前を IEAddOn.cs に変更します。
「ツール」「GUID の作成」から独自にGUIDを生成して(書式は5番)、IObjectWithSite インターフェイスの実装を兼ねて次のようにコーディングします。

IEAddOn.cs

using System;
using System.Linq;
using System.Runtime.InteropServices;
using mshtml;
using SHDocVw;
using Microsoft.Win32;

namespace SampleIEAddOn
{
    [ComVisible(true),
     ClassInterface(ClassInterfaceType.None),
     Guid("????????-????-????-????-????????????")] // <- 生成したGUID
    public class IEAddOn : IObjectWithSite
    {
        #region COMBHOの登録と解除 - regasm ツールで呼ばれます。
        private const string BHOKEYNAME = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Browser Helper Objects";

        [ComRegisterFunction]
        public static void RegisterBHO(Type type)
        {
            RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(BHOKEYNAME, true);

            if (registryKey == null)
                registryKey = Registry.LocalMachine.CreateSubKey(BHOKEYNAME);

            string guid = type.GUID.ToString("B");
            RegistryKey ourKey = registryKey.OpenSubKey(guid);

            if (ourKey == null)
                ourKey = registryKey.CreateSubKey(guid);

            ourKey.SetValue("Alright", 1);
            registryKey.Close();
            ourKey.Close();
        }

        [ComUnregisterFunction]
        public static void UnregisterBHO(Type type)
        {
            RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(BHOKEYNAME, true);
            string guid = type.GUID.ToString("B");

            if (registryKey != null)
                registryKey.DeleteSubKey(guid, false);
        }
        #endregion


        private WebBrowser webBrowser;

        public int GetSite(ref Guid guid, out IntPtr ppvSite)
        {
            IntPtr punk = Marshal.GetIUnknownForObject(webBrowser);
            int hr = Marshal.QueryInterface(punk, ref guid, out ppvSite);
            Marshal.Release(punk);

            return hr;
        }

        public int SetSite([MarshalAs(UnmanagedType.IUnknown)] object site)
        {
            if (site != null)
            {
                webBrowser = site as WebBrowser;
                webBrowser.DocumentComplete += WebBrowser_DocumentComplete; // DocumentCompleteイベントを利用する例
                webBrowser.BeforeNavigate2 += WebBrowser_BeforeNavigate2; // BeforeNavigate2イベントを利用する例
            }
            else
            {
                webBrowser.DocumentComplete -= WebBrowser_DocumentComplete;
                webBrowser.BeforeNavigate2 -= WebBrowser_BeforeNavigate2;
                webBrowser = null;
            }

            return 0;
        }

        private void WebBrowser_BeforeNavigate2(object pDisp, ref object URL, ref object Flags, ref object TargetFrameName, ref object PostData, ref object Headers, ref bool Cancel)
        {
            System.Windows.Forms.MessageBox.Show("ナビゲート開始"); // 参照に System.Windows.Forms アセンブリを追加
        }

        private void WebBrowser_DocumentComplete(object pDisp, ref object URL)
        {
            var document = (HTMLDocument)webBrowser.Document;
            var titleText = document.getElementsByTagName("title")
                .Cast<IHTMLElement>()
                .FirstOrDefault()?.innerText ?? "空のタイトル";
            System.Windows.Forms.MessageBox.Show(titleText); // 参照に System.Windows.Forms アセンブリを追加
        }
    }
}

アドオンとして登録

管理者権限で regasm ツールを使用して(スタートメニュー Visual Studio 2019 内の "Developer Command Prompt for VS2019" からが便利)、レジストリ登録します。厳密名の使用をお勧めされるので、本格開発では検討しましょう。

  • 登録
    regasm /codebase <.dllファイルのフルパス>

  • 登録解除
    regasm /unregister <.dllファイルのフルパス>

試す

Internet Explorer(インターネットエクスプローラー)を起動してみます。初回「不明な発行元 '.....' が使えるようになりました」と下部に表示されるので「有効にする」を選択します。

サンプルでは、メッセージボックスが表示されます。うざったいと思いますので、結果を確認出来たら「アドオンの管理」から無効にするか、アンインストール(unregister)してください。

参考にした情報源(感謝)

  1. 「IEを使わないで」ではなくて「IEを既定にしないで」 - 山市良のうぃんどうず日記@IT

6
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?