Visual Studio.NET 2005を使った開発でのMSHTML問題とその対策

●概要
 VB.NET 2005やC# 2005での開発で、Internet Explorerを操作するにあたり
 MSHTML(Microsoft HTML Object Library)を使用している場合に何かと問題が発生する。

●発生した現象 その1
 MSHTMLを参照設定で組み込んだアプリケーションを、.NetFramework 2.0ランタイムが入ったPCで動作させようとした所、下記のエラーメッセージが表示される。
 「Could not load file or assembly 'Microsoft.mshtml, Version=7.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. 指定されたファイルが見つかりません。」

●原因 その1
 理由はよくわからないが、.NetFramework 2.0のMSHTMLは、SDKではassemblyが登録されるが、ランタイムでは登録されない。
 なお、ClickOnesなど、セットアップ作成プログラムを利用しても、自動では収集して来ない。

●対策 その1
 1.Microsoft.mshtml.dllをアプリケーションと同じディレクトリにコピーする
 2.参照設定を解除し、遅延バインディングを利用する


●発生した現象 その2
 対策 その1の1でやったが、うちの環境では問題が出てしまった。メッセージは下記になる。
 「Unable to cast COM object of type 'System.__ComObject' to class type 'mshtml.HTMLDocumentClass'. COM components that enter the CLR and do not support IProvideClassInfo or that do not have any interop assembly registered will be wrapped in the __ComObject type. Instances of this type cannot be cast to any other class; however they can be cast to interfaces as long as the underlying COM component supports QueryInterface calls for the IID of the interface.」
 これは、人によってHTMLDocumentClassの部分が変わるのでは無いかと思う。

●原因 その2
 簡単に言ってしまうとCASTによるエラーが発生している。ComObjectから明確にクラスを利用して変数宣言している場合、その変数へ割り当てる瞬間にCASTのエラーとなる。
 (例) VB.NETでいうと、この様な変数定義をしているとエラーになる。
 Dim htmlDocumentClass As HTMLDocumentClass
 このhtmlDocumentClassに値を設定すると、キャスト違反…

●対策 その2
 1..NetFramework 2.0 SDKをセットアップする(^^;
 2.参照設定を解除し、遅延バインディングを利用する


●発生した現象 その3
 対策 その2の1でやったが、お客様の環境で問題が出てしまった(oo;

●原因 その3
 .NetFramework 1.1が入っていると、結局現象その2が出てしまった…

●対策 その3
 .NetFramework 1.1が入っている環境に入れる場合は、参照設定を解除し、遅延バインディングを利用するしか無いらしい…


「対策したコードはこんな感じでやるらしい」
http://support.microsoft.com/default.aspx?scid=kb;JA;305622
とても面倒くさい。

そこで良く考えてみた。そう今回はVB.NETだった。
なので、VBっぽくやる事で遅延バインディングに対応してしまおう作戦に出た。

「エラーになっていたコード」
Dim internetExplorer As InternetExplorer
Dim htmlDocument As HtmlDocument
internetExplorer = New InternetExplorer()
htmlDocument = internetExplorer.Document

「対策コード」
Dim internetExplorer As Object
Dim htmlDocument As Object
internetExplorer = CreateObject("InternetExplorer.Application")
htmlDocument = internetExplorer.Document

エラー箇所を突破!VBは最強です(w

その後、気が付いた事ではあるが、このObject型に対してTypeNameを実行すると以下の様になる。
・.NetFramework 2.0 SDK
 「HtmlDocumentClass」
・.NetFramework 2.0 Runtime
 「HtmlDocument」

このやり方で対応をしようと思う方で、クラスの型で処理を分けている人は、両方判定する様にする事をお勧めします。