WebBrowser

クラス階層

  • System.ComponentModel.Component
    • System.Windows.Forms.Control
      • System.Windows.Forms.WebBrowserBase
        • System.Windows.Forms.WebBrowser

プロパティ

プロパティ  
bool AllowNavigation falseならば初期ページから移動できず、ハッシュ (#) によるページ内遷移も認められない
bool AllowWebBrowserDrop trueならば、コントロールにドロップされたドキュメントに移動する
※ただしAllowNavigationがtrueでなければ移動しない
bool CanGoBack  
bool CanGoForward  
HtmlDocument Document ドキュメントのコンテンツを表すHtmlDocument
Stream DocumentStream ドキュメントのコンテンツを表すStream
string DocumentText ドキュメントのコンテンツを表すString
string DocumentTitle ドキュメントのタイトル
string DocumentType ドキュメントの種類。"ファイル"など
WebBrowserEncryptionLevel EncryptionLevel  
bool Focused  
bool IsBusy  
bool IsOffline  
bool IsWebBrowserContextMenuEnabled trueならば、コンテキストメニューが有効 [既定はtrue]
object ObjectForScripting  
Padding Padding  
WebBrowserReadyState ReadyState  
bool ScriptErrorsSuppressed trueならば、スクリプトエラーのダイアログを表示しない
bool ScrollBarsEnabled trueならば、ページのコンテンツがコントロールよりも大きいときにスクロールバーを表示する
string StatusText  
Uri Url 現在のドキュメントのURL。これに設定することはNavigate()の呼び出しと等しい
Version Version  
bool WebBrowserShortcutsEnabled trueならば、キーボード ショートカットが有効 [既定はtrue]
プロパティ - WebBrowser クラス (System.Windows.Forms) | MSDN

次の2つのプロパティは、既定値のtrueからfalseに変更しようとするとErrorCode -2147467259 (0x80004005:Unspecified failure) で、COMException例外が発生することがあります。

  • AllowWebBrowserDrop
  • ScrollBarsEnabled

その場合にはこれらのプロパティは、コントロールが表示されてからDocumentCompletedが発生する前に設定します。WebBrowser Control creates COM Exception

Document

Webページの要素にアクセスできます。WebBrowser.Document プロパティ (System.Windows.Forms) | MSDN

新しいページを読み込ませたときには、DocumentCompletedイベントの発生を待ってからDocumentへアクセスします。さもなくばnullが返されます。

HtmlDocument document = webBrowser.Document; // null

webBrowser.DocumentCompleted += delegate
{
    document = webBrowser.Document; // "System.Windows.Forms.HtmlDocument"
};

webBrowser.Navigate("about:blank");

DocumentText

ドキュメントのコンテンツを表す文字列です。このプロパティに文字列を設定すると、それが適用される前にabout:blankが自動的に読み込まれます。そしてそのとき、

  • Navigating
  • Navigated
  • DocumentCompleted

の各イベントが発生します。解説 - WebBrowser.DocumentText プロパティ (System.Windows.Forms) | MSDN

メソッド

メソッド  
GoBack()  
GoForward()  
GoHome()  
GoSearch()  
Navigate(string)  
Print()  
Refresh()  
ShowPageSetupDialog()  
ShowPrintDialog()  
ShowPrintPreviewDialog()  
ShowPropertiesDialog()  
ShowSaveAsDialog()  
Stop()  
WebBrowser()  
メソッド - WebBrowser クラス (System.Windows.Forms) | MSDN

Navigate

  URLの指定方法 新規ウィンドウ フレーム POST
Navigate(String) Stringクラス × × ×
Navigate(String, Boolean) × ×
Navigate(String, String) × ×
Navigate(String, String, Byte[], String) ×
Navigate(Uri) Uriクラス × × ×
Navigate(Uri, Boolean) × ×
Navigate(Uri, String) × ×
Navigate(Uri, String, Byte[], String) ×
WebBrowser.Navigate メソッド (System.Windows.Forms) | MSDN

AllowNavigationがfalseに設定されていると、初回以外のURLの指定は無視されます。

このメソッドをWebBrowserBase.OnHandleCreated()内で呼び出すと、COMException「エラー HRESULT E_FAIL が COM コンポーネントの呼び出しから返されました。」ErrorCode=-2147467259 (0x80004005) が発生します。

イベント

イベント 発生タイミング
EventHandler CanGoBackChanged CanGoBackプロパティの値が、変更されたとき
EventHandler CanGoForwardChanged CanGoForwardプロパティの値が、変更されたとき
EventHandler DocumentTitleChanged DocumentTitleプロパティの値が、変更されたとき
EventHandler StatusTextChanged StatusTextプロパティの値が、変更されたとき
WebBrowserNavigatingEventHandler Navigating 新しいドキュメントへ移動する前
WebBrowserNavigatedEventHandler Navigated 新しいドキュメントへ移動し、読み込みを開始したとき
CancelEventHandler NewWindow 新しいウィンドウが開かれる前
WebBrowserProgressChangedEventHandler ProgressChanged 移動先のドキュメントのダウンロードの情報が更新されたとき
WebBrowserDocumentCompletedEventHandler DocumentCompleted ドキュメントの読み込みが完了したとき
EventHandler EncryptionLevelChanged 暗号を使用するサイトへの訪問または離脱したとき
EventHandler FileDownload ファイルがダウンロードされるとき
イベント - WebBrowser クラス (System.Windows.Forms) | MSDN

これらはWebBrowserコントロールのイベントであり、DOMのイベントはAttachEventHandler()で捕捉できます。

新しいドキュメントへ移動するときは、

  1. Navigating
  2. Navigated
  3. ProgressChanged
  4. DocumentCompleted

の順でイベントが発生します。

NewWindow

新しいウィンドウが開く前に発生します。

public event CancelEventHandler NewWindow
WebBrowser.NewWindow イベント (System.Windows.Forms) | MSDN

新規ウィンドウのURLの取得

NewWindow2イベント

DocumentCompleted

ドキュメントの読み込みが完了した後に発生します。

public event WebBrowserDocumentCompletedEventHandler DocumentCompleted
WebBrowser.DocumentCompleted イベント (System.Windows.Forms) | MSDN

ページ内にframeがあると、DocumentCompletedイベントはそのframeごとに発生します。よって全体の読み込みが完了したことは別に判定する必要があり、それには読み込まれたURL (e.Url) と現在のページのURL (((WebBrowser)sender).Url) が等しいことを確認します。

private void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
    if (e.Url == ((WebBrowser)sender).Url)
    {
    }
}

コンテンツの作成

外部のリソースを読み込むのではなく、HTMLでコンテンツを作成する方法を考えます。

HTMLからコンテンツを作成した場合、ドキュメントのURLは"about:blank"となり、他のリソースへは相対パスでアクセスできません。

HTMLコードで作成

HTMLコードを文字列で記述します。それにはDocumentTextプロパティに設定するか、Document.Write()メソッドを呼び出します。

webBrowser.DocumentText = "<B>ABC</B>";
WebBrowserコントロールのコンテンツを文字列により設定するには?[2.0、C#、VB] - @IT 遠藤孝信 (2008/08/07)

DocumentTextへの設定は、DocumentCompletedイベントの発生まで適用されません。

DOMで作成

DocumentプロパティからHtmlDocumentを取得したら、後はJavaScriptでDOMを処理するのと同じ要領で作成できます。

WebBrowserDocumentCompletedEventHandler handler = null;
handler = delegate
{
    webBrowser.DocumentCompleted -= handler;

    HtmlDocument document = webBrowser.Document;

    HtmlElement element = document.CreateElement("b");
    element.SetAttribute("title", "foo");
    element.InnerText = "ABC";

    document.Body.AppendChild(element);
};
webBrowser.DocumentCompleted += handler;
webBrowser.Navigate("about:blank");

ただしHtmlDocumentにはcreateTextNode()がないため、テキストノードを直接作成できません。よってその必要があるならばIHTMLDocument3オブジェクトを取得し、それのcreateTextNode()を用います。

HtmlDocument document = webBrowser.Document;
mshtml.IHTMLDocument2 htmlDocument2 = (mshtml.IHTMLDocument2)document.DomDocument;
mshtml.IHTMLDocument3 htmlDocument3 = (mshtml.IHTMLDocument3)document.DomDocument;

mshtml.IHTMLDOMNode body = (mshtml.IHTMLDOMNode)htmlDocument2.body;

mshtml.IHTMLElement element = htmlDocument2.createElement("b"); // 要素の作成
element.innerText = "ABC";
body.appendChild((mshtml.IHTMLDOMNode)element);

mshtml.IHTMLDOMNode text = htmlDocument3.createTextNode("DEF"); // テキストノードの作成
body.appendChild(text);

string html = document.Body.InnerHtml; // "<B>ABC</B>DEF"

または単純に、InnerHtmlまたはInnerTextに文字列を設定しても同じです。

webBrowser.Document.Body.InnerHtml = "<B>ABC</B>DEF";

mshtml名前空間のクラスを利用するには、Microsoft.mshtmlを参照に追加します。

createTextNode()
IHTMLDOMNode retVal = object.createTextNode(text);
createTextNode method (Windows) | MSDN

イベント ハンドラの追加

public void AttachEventHandler(
    string eventName,         // 捕捉するイベントの名前
    EventHandler eventHandler // イベントを捕捉するマネージド コード
)
HtmlElement.AttachEventHandler Method (String, EventHandler) (System.Windows.Forms) | MSDN

AttachEventHandlerによるハンドラの追加は、DocumentCompletedイベントの発生を待ってから行います。

senderの特定

たとえばclickイベントは、次のようにAttachEventHandler()で捕捉できます。

{
    HtmlDocument document = webBrowser.Document;
    HtmlElement element = document.CreateElement("button");
    element.SetAttribute("value", "Click me");

    element.AttachEventHandler("onclick", new EventHandler(Element_Click));
}

private void Element_Click(object sender, EventArgs e)
{
    // senderはnull
}

ただしこの方法ではハンドラ内でsenderを特定できないため、その情報が必要ならばHtmlElement.Clickイベントを用います。

    // (省略)
    element.Click += new HtmlElementEventHandler(Element_Click);
}

private void Element_Click(object sender, HtmlElementEventArgs e)
{
    HtmlElement element = (HtmlElement)sender;
}

しかしHtmlElementにそのイベントが用意されていなければこの方法は適用できないため、より汎用的には匿名メソッドを用いて、そのメソッド内からelementのインスタンスをsenderとして渡します。AttachEventHandler fires with sender==null and empty EventArgs, so how to get the value of a SELECT element?

    // (省略)
    element.AttachEventHandler("onclick", delegate
    {
        Element_Click(element, EventArgs.Empty);
    });
}

private void Element_Click(HtmlElement element, EventArgs e)
{
}
イベントの発生

指定要素でイベントを発生させ、それに登録されているイベント ハンドラを呼び出せます。

public void RaiseEvent(
    string eventName
)
HtmlElement.RaiseEvent メソッド (String) (System.Windows.Forms) | MSDN
elememt.RaiseEvent("onclick");

同様の処理は、InvokeMember()ならば次のように記述します。HtmlElement.InvokeMember メソッド (String) (System.Windows.Forms) | MSDN

elememt.InvokeMember("click");
イベント ハンドラの削除

AttachEventHandler()で取り付けたハンドラは、DetachEventHandlerで取り外せます。

public void DetachEventHandler (
    string eventName,
    EventHandler eventHandler
);
HtmlElement.DetachEventHandler(String, EventHandler) Method (System.Windows.Forms) | Microsoft Learn
element.AttachEventHandler("onclick", Element_Click); // ハンドラの登録

// ...

element.DetachEventHandler("onclick", Element_Click); // ハンドラの削除

トラブル対処法

デバッグ時にハングアップする

次の3条件が満たされるとき、WebBrowserが含まれるコントロールが表示されるときにアプリケーションがハングアップします。

  • デバッグのオプションで、[マネージ互換モードの使用]が有効
  • プロジェクトのプロパティで、[ネイティブ コードのデバッグを有効にする]が有効
  • プロジェクトのプラットフォームがx86

よってデバッグの設定を修正します。

MSHTMLを読み込めない

Microsoft HTML Object Library (Microsoft.mshtml) を参照しているとき、「warning MSB3283: タイプ ライブラリ "MSHTML" のラッパー アセンブリが見つかりません。(warning MSB3283: Cannot find wrapper assembly for type library "MSHTML".)」として、そのアセンブリの読み込みに失敗することがあります。そのときにはまず、参照しているファイル%WINDIR%\assembly\GAC\Microsoft.mshtml\7.0.3300.0__b03f5f7f11d50a3a\Microsoft.mshtml.dllを確認し、それが誤っているならば修正します。

解決方法1:Visual Studioを更新する

適用できる更新があるならばそれを実行することで、解決されることがあります。

解決方法2:アセンブリを登録し直す

アセンブリ登録ツール (RegAsm) で、Microsoft.mshtml.dllを登録し直します。Fixing 'Cannot find wrapper assembly for type library "MSHTML"' After Windows 10 Upgrade

MSHTMLを読み込めるようになった後に「参照コンポーネント MSHTML には、更新された使用可能なカスタム ラッパーがあります。(There are updated custom wrappers available for the following referenved components: Mshtml)」と警告されることがありますが、これはVisual Studioを再起動することで解決できます。

解決方法3:プライマリ相互運用アセンブリ (Primary Interop Assemblies : PIA) を利用する

参照するアセンブリを、参照マネージャーの【アセンブリ → 拡張】にあるMicrosoft.mshtmlに変更します。この実体は%PROGRAMFILES(X86)%\Microsoft.NET\Primary Interop Assemblies\Microsoft.mshtml.dllにあります。プライマリ相互運用アセンブリ (PIA) | MSDN

Microsoft Learnから検索