👻

WPFにおけるWebView2実装と機能紹介

に公開

はじめに

WPFでWebView2を使い始めたときにまず調べたこと、気をつけたことをまとめておきます。

  • 初期化の順番
    EnsureCoreWebView2Async() 実行前にイベントを設定すると動作しない場合があるため、初期化後に購読する。

  • ユーザーデータフォルダ
    Cookieやセッションを維持したい場合は CoreWebView2Environment.CreateAsync(null, path) で保存先を指定する。

  • イベントの種類

    • NavigationStarting … 遷移開始時(OAuthコールバック検知などに利用)
    • NavigationCompleted … 遷移完了時(ページ描画後の処理に利用)
    • WebMessageReceived … Webページ ↔ アプリ間のメッセージ受信
  • 双方向通信の方法

    • WPF → Web … PostWebMessageAsString / PostWebMessageAsJson
    • Web → WPF … chrome.webview.postMessage()WebMessageReceived
  • セキュリティ
    外部サイト連携時は送信元ドメインを検証。OAuthでは state パラメータ検証を必須に。


1. 基本セットアップ

NuGet

Install-Package Microsoft.Web.WebView2

XAML

<Window x:Class="SampleApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:wv2="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"
        Title="WebView2 Sample" Height="450" Width="800">

    <Grid>
        <wv2:WebView2 x:Name="WebView"
                      HorizontalAlignment="Stretch"
                      VerticalAlignment="Stretch"/>
    </Grid>
</Window>

C#

using Microsoft.Web.WebView2.Core;
using System;
using System.Threading.Tasks;
using System.Windows;

namespace SampleApp
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            Loaded += async (_, __) => await InitializeWebViewAsync();
        }

        private async Task InitializeWebViewAsync()
        {
            var env = await CoreWebView2Environment.CreateAsync();
            await WebView.EnsureCoreWebView2Async(env);

            // イベント購読(初期化後に設定)
            WebView.NavigationCompleted += OnNavigationCompleted;
            WebView.CoreWebView2.WebMessageReceived += OnWebMessageReceived;

            // ページを開く
            WebView.Source = new Uri("https://localhost:5001/index.html");
        }

        private void OnNavigationCompleted(object sender, CoreWebView2NavigationCompletedEventArgs e)
        {
            MessageBox.Show($"ページロード完了: {WebView.Source}");
        }

        // Web → WPF
        private void OnWebMessageReceived(object sender, CoreWebView2WebMessageReceivedEventArgs e)
        {
            string message = e.TryGetWebMessageAsString();
            MessageBox.Show($"Webからのメッセージ: {message}");
        }

        // WPF → Web(文字列)
        private void SendMessageToWeb()
        {
            WebView.CoreWebView2.PostWebMessageAsString("Hello from WPF!");
        }

        // WPF → Web(JSON)
        private void SendJsonToWeb()
        {
            var json = "{\"type\":\"greeting\",\"text\":\"Hello from WPF JSON!\"}";
            WebView.CoreWebView2.PostWebMessageAsJson(json);
        }
    }
}

2. Web側実装例(JavaScript)

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <title>WebView2 Communication</title>
  <script>
    window.addEventListener("DOMContentLoaded", () => {
      // WPFからのメッセージ受信
      window.chrome.webview.addEventListener('message', event => {
        console.log("WPFから受信:", event.data);
        document.getElementById("log").innerText += "\n" + JSON.stringify(event.data);
      });

      // ボタンクリックでWPFへメッセージ送信
      document.getElementById("sendBtn").addEventListener("click", () => {
        chrome.webview.postMessage("Hello from Web!");
      });
    });
  </script>
</head>
<body>
  <h1>WebView2通信テスト</h1>
  <button id="sendBtn">WPFへ送信</button>
  <pre id="log"></pre>
</body>
</html>

3. WebView2 の主な機能と用途

機能カテゴリ 説明 実装例
ページ遷移制御 Navigate / Sourceで任意URLへ移動 WebView.Source = new Uri(...)
イベントフック NavigationStarting(遷移開始)、NavigationCompleted(遷移完了)、DOMContentLoaded(DOM構築後) WebView.NavigationCompleted += ...
JavaScript実行 Web側でスクリプトを実行 await WebView.ExecuteScriptAsync("alert('test')");
双方向通信(Web→WPF) JS → C# メッセージ送信 chrome.webview.postMessage() + WebMessageReceived
双方向通信(WPF→Web) C# → JS メッセージ送信 PostWebMessageAsString / PostWebMessageAsJson
ユーザーデータフォルダ管理 CookieやLocalStorage保持 CoreWebView2Environment.CreateAsync(null, path)
カスタムスキーム対応 NavigationStartingで検知し処理 OAuthコールバック検知など

4. OAuthコールバックの検知例

WebView.NavigationCompleted += (s, e) =>
{
    var url = WebView.Source.AbsoluteUri;
    if (url.Contains("/auth?res=success"))
    {
        var query = System.Web.HttpUtility.ParseQueryString(new Uri(url).Query);
        var token = query["token"];
        MessageBox.Show($"認証成功: token={token}");
    }
};
WebView.CoreWebView2.NavigationStarting += (s, e) =>
{
    var uri = new Uri(e.Uri);
    if (uri.AbsolutePath == "/auth" && uri.Query.Contains("res=success"))
    {
        var query = System.Web.HttpUtility.ParseQueryString(uri.Query);
        var token = query["token"];
        e.Cancel = true; // ページ遷移を止める
        MessageBox.Show($"認証成功: token={token}");
    }
};

5. 実務での利用シーン

  • デスクトップアプリ内でのSPA(React/Vue等)の組み込み
  • OAuth / OIDC 認証フローのコールバック処理
  • データ可視化ライブラリ(D3.js, Chart.js等)をWPF内に埋め込み
  • ローカルアプリからWebサービスへのデータ送信・受信

まとめ

WebView2を使えば、WPFアプリにモダンなWeb機能を統合し、UI/UXを大幅に向上できます。

  • ページ遷移検知:NavigationStarting / NavigationCompleted
  • 双方向通信:WebMessageReceivedPostWebMessageAsString/Json
  • セキュリティ:必ずドメイン検証やstateチェックを行う

Discussion