【C#】WebView2お試し

# 初めに

WindowsのWebViewはIEが元、WebView2はChromiumベースのEdgeが元です。
ごく個人的にはWindows上でのWebViewを直近で必要とはしていないですが
IE終了の今とりあえず動かせるようにしておくための記録です。

- NuGetでWebView2関連を取得
- WebView2をフォームにペタる
- URLを叩く
- JavaScriptを叩く

まで行います。

# 環境

OS:Windows10 バージョン21H2
開発環境:Visual Studio 2022 Enterprise (※大したことはしてないのでCommunity Editionでも動くと思います。）
.Net Framework4.6 + Windows Forms で今回は作成。

WebView2のランタイムをNuGetで入れるので必要ないかもですが、Windows10の方はこれを機にWebView2を入れておくのがよいかもです。

https://developer.microsoft.com/ja-jp/microsoft-edge/webview2/

# 一式欲しい方は

一式欲しい！という方はGitHubに置いたのでCloneしてください。
https://github.com/fu-foo/WebView2Sample

# とりあえずソース全景を見たい方は

<details><summary>ソースコードを表示（折りたたみ）</summary><div>

```C#:Form1.cs
using System.Windows.Forms;
using Microsoft.Web.WebView2.Core;

namespace Fu.WebView2Sample
{
    /// <summary>
    /// 最低限のWebView2サンプル(yahoo.co.jpを開く→検索文字列をセット→検索）
    /// </summary>
    public partial class Form1 : Form
    {
        /// <summary>
        /// フォーム初期化
        /// </summary>
        public Form1()
        {
            InitializeComponent();

            // WebView2初期化完了イベント追加
            this.webView2.CoreWebView2InitializationCompleted += this.WebView2InitializationCompleted;

            // WebView2初期化完了確認
            this.webView2.EnsureCoreWebView2Async(null);
        }

        /// <summary>
        /// WebView2初期化完了イベント
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void WebView2InitializationCompleted(object sender, CoreWebView2InitializationCompletedEventArgs e)
        {
            if (e.IsSuccess)
            {
                // どこぞやのURL
                this.webView2.CoreWebView2.Navigate("https://url_you_wanna_go");

                // 遷移完了のイベント追加
                this.webView2.CoreWebView2.NavigationCompleted += this.webView2_NavigationCompleted;
            }
            else
            {
                // エラー処理
            }
        }

        /// <summary>
        /// 遷移完了後イベント
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void webView2_NavigationCompleted(object sender, CoreWebView2NavigationCompletedEventArgs e)
        {
            if (e.IsSuccess)
            {
                // 実行したいJavaSciprtを記載　※サンプル：name:pppppのタグに"C#"の文字列をセット
                this.webView2.ExecuteScriptAsync("document.getElementsByName('ppppp').item(0).value = 'C#';");
            }
            else
            {
                // エラー処理
            }
        }
    }
}
```
</div></details>


# 解説

## NuGet で必要なものを取得

- Microsoft.Web.WebView2
- WebView2.Runtime.X64 (※今回は64bitで割り切ってますが32bitでいきたい場合はX86を取得してください。)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138460/26520061-a4fc-dc5e-2680-a16b431ebc3a.png)

## コントロール貼り付け

NuGetで取得できたらツールボックスにWebView2が追加されているので、ポトってペタります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138460/1ef312c9-0018-d2c5-6685-6c583d977b6f.png)

今回は何も考えずWebView2をフォーム内いっぱいにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138460/0d04a577-ca57-3fd7-5717-41039b9bf845.png)

## ソース解説

Edgeは起動に時間がかかるため「起動終わったかい？」と待つのがルールなようです。
EnsureCoreWebView2Asyncを叩いて初期化が終わればCoreWebView2InitializationCompletedイベントが発生するようにイベント追加しておきます。

```C#:Form1.cs
public Form1()
{
    InitializeComponent();

    // WebView2初期化完了イベント追加
    this.webView2.CoreWebView2InitializationCompleted += this.WebView2InitializationCompleted;

    // WebView2初期化完了確認
    this.webView2.EnsureCoreWebView2Async(null);
}
```

今回はWebView2の初期化が終わったらどこぞやのサイトに飛ぶこととします。
※よそ様のサイトを実験台にはできないので任意のURLを指定してください。何か問題があっても責任は負えません。悪しからず。

ただURLを指定して遷移するだけならこれで終わりですが、遷移後にもう少し処理をしたいので、
遷移後のイベントを追加します。

```C#:Form1.cs
private void WebView2InitializationCompleted(object sender, CoreWebView2InitializationCompletedEventArgs e)
{
    if (e.IsSuccess)
    {
        // どこぞやのURLに遷移
        this.webView2.CoreWebView2.Navigate("※どこぞやのURL");

        // 遷移完了のイベント追加
        this.webView2.CoreWebView2.NavigationCompleted += this.webView2_NavigationCompleted;
     }
     else
     {
        // エラー処理
     }
}
```

遷移後、出力された内容にゴニョゴニョっとしてみたいと思います。
DOMの操作は専用メソッドがあるわけではなくExecuteScriptAsyncでJavaScriptを叩きます。


ということで、どこぞやのサイトでnameが'hoge※'のタグに'C#'の文字を入れましょう。
（※hogeは実際の値ではないので、各サイトの中をお探しください。）

```C#:Form1.cs
private void webView2_NavigationCompleted(object sender, CoreWebView2NavigationCompletedEventArgs e)
{
    if (e.IsSuccess)
    {
        // 実行したいJavaScriptを書く
        this.webView2.ExecuteScriptAsync("document.getElementsByName('hoge').item(0).value = 'C#';");
    }
    else
    {
        // エラー処理
    }
}
```

## 結果

フォームに張り付けたWebView2で某URLにアクセスして、検索窓に'C#'と入れられました。
ExecuteScriptAsyncでJavaScriptをひたすら叩けるので色々できますね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138460/f29bdc4a-cb7e-c8fe-775f-0ddfe1a2808d.png)

# 公式ドキュメント

とりあえず動せたので細かいことは公式ドキュメントを参照であとは何とかなりそうです。

https://learn.microsoft.com/ja-jp/microsoft-edge/webview2/webview2-api-reference?view=webview2-dotnet-1.0.1370.28