【配布有】しらたまちゃんと学ぶWPFのWebView2実装#2【ビルド&機能カスタマイズ編Part1】

**Powered by ABATBeliever, with しらたまちゃん**

<h1>目次</h1>
前回

https://qiita.com/ABATBeliever/items/e95fed5a38077d59b50a


- 免責
- 振り返り
  - コード
  - 開発につかった環境
- 開発！
  - 1.プロジェクト読み込み
  - 2.アセットファイルと仮想ウェブサイト
  - 3.仮想じゃない純粋なローカルファイル
  - 4.WebViewの機能を見ようね
  - 5.バグ
  - 6.本ビルドしてみよう
  - 7.本当に動く?
- まとめ
- 次回へ続く

<h1>免責</h1>

・ABATBelieverは初心者です。この記事が正しいとは限りません。

・使用するサンプルコードはMicrosoftがBSDライセンスをかけています。

・私が公開しているサンプルコードのBSDはMicrosoftのやつベースだからつけてます。

<h1>振り返り</h1>
<h2>コード</h2>
前回、環境セットアップとファイル解説、基本的な部分の翻訳などをやりました。
前回記事を読んで自分で書くか、サンプルコードを入手してください。

MSのコード

https://github.com/MicrosoftEdge/WebView2Samples

Part#1相当

https://github.com/ABATBeliever/Siratama_WPF_WebView2_Browser/releases/tag/%231

今回出来上がるやつ

https://github.com/ABATBeliever/Siratama_WPF_WebView2_Browser/releases/tag/%232

<h2>開発に使った環境</h2>
<h3>Microsoft Visual Studio 2022 無料版</h3>
<h3>Windows11 23H2</h3>
<h3>8世代i5,8GB,100GB(ハードオフで3万未満)</h3>

<h1>開発！</h1>
<h2>1.プロジェクト読み込み</h2>
前回できあがったもの

![スクリーンショット 2024-01-06 020339.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3668884/770878a6-2353-ea95-4c52-3ee589b5326a.png)

SiratamaMain(などの名前).sln　(プロジェクトファイル)を押して開きなおそう。

<h2>2.アセットファイルと仮想ウェブサイト</h2>

MainWindow.xaml.cs の1969行目から、初めに起動するURLを指定できる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3668884/c9202a29-14ad-6729-0d50-2fa7ba824a42.png)

すぐ下にある「webView.CoreWebView2.SetVirtualHostNameToFolderMapping」は

~~~
WebView2 コントロールにローカル コンテンツを読み込むもう 1 つの方法は、
仮想ホスト名マッピングを使用することです。 これには、ローカル ドメイン名を
ローカル フォルダーにマッピングする必要があるため、WebView2 コントロールが
そのドメインのリソースを読み込もうとすると、代わりに指定されたローカル フォルダーの
場所からコンテンツが読み込まれます。 ドキュメントの配信元も仮想ホスト名になります。

この方法では、列挙型を使用して、クロスオリジン アクセスを 
CoreWebView2HostResourceAccessKind 指定できます。
~~~
https://learn.microsoft.com/ja-jp/microsoft-edge/webview2/concepts/working-with-local-content?tabs=dotnetcsharp

とのこと。要は、下の画像の場合
「https://ThisIsNotWebSite.example.index/〇〇.html」 はローカルフォルダ内の「assets/〇〇.html」に対応しているということ。

もちろんほかのブラウザだと「そんなページはねえ」と怒られるので、仮想的なサイトを作れるらしい。

これをうまく活用すれば組み込みアプリや社内システムに使えそうだ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3668884/47e0e367-7f0e-0829-5a47-bfe36c6031c2.png)

写真では起動時にそのページを開くようにしているが、上のStringを例えばGoogleにすれば初期でgoogle.comが開くってわけ

<h2>3.仮想じゃない純粋なローカルファイル</h2>
file://〇〇
の形式で開く。

これはほかのブラウザでも開けてしまうが簡単。

画像ビューワーとかの使い方もできる。(?)

<h2>4.WebViewの機能を見ようね</h2>
<h3>ブラウザータスクマネージャー [WebView2]</h3>
WebView2で実装されたタスクマネージャー。
taskmgr.exeとは別。

しらたまWPFでは
**スクリプト>Taskmgr**
で起動できる。

MicrosoftEdgeではShift+ESCで同じのが出てくる。

ここではxamlのUIで起動操作が起こった際にxaml.cs経由でWebView2に開くよう要請している。

<h3>開発者ウィンドウ [WebView2]</h3>
WebView2で実装された開発者ウィンドウ。

しらたまWPFでは
**スクリプト>開発者向けウィンドウ**
で起動できる。

ここでもxamlのUIで起動操作が起こった際にxaml.cs経由でWebView2に開くよう要請している。

<h3>最大化抑制[コード?]</h3>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3668884/c3bb33c3-8cf4-19c0-cec7-631bec27758c.png)

適当に私のyoutube動画を全画面表示した写真なのだが、全画面表示がなんかおかしいことに気づいただろうか。(URLもおかしいんだけどそれはまあ置いといて。)

ウィンドウサイズが変わっていないのだ。
(まあ普通にこれも便利だけど)

実はウィンドウ関連でもう一つやべえバグがあるのだが、それは後ほど。

<h3>ミュート機能 [コード]</h3>
xamlの2328行目あたりにある。
ここではミュートの有効化/無効化をつかさどっている。
おまけとして、ウィンドウにUnicodeのアイコンが加わるようにしている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3668884/b2f7c5a3-d912-0af9-f66a-9a70510c2659.png)

しらたまWPFでは
**音>ミュート**
から変更できる。

<h2>5.バグ</h2>
ウィンドウ関係の重大すぎるバグがある。厳密には仕様だが。
<br>
<h3>不正な新規ウィンドウを呼び出すと全プロセスが道連れになる</h3>
しらたまWPFブラウザはプロセスを複製することができ、オプションも指定できる。

これは例えば組み込みアプリでメインウィンドウと認証ウィンドウがいる際などに使えそうなのだが、

**ウィンドウ>新規:ウィンドウ With Options**
で適当な値を入れて「OK」を押してみてほしい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3668884/72e6bdbb-7fe5-0086-dfb9-2688d879bb61.png)
    すると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3668884/41ac942b-65bc-7867-5180-b5472e4f25a7.png)
とまあこんな感じでクラッシュしてしまう。

古いほうのレンダリングは問題なさそうに見えるが、ウィンドウの応答がなくなって閉じられなくなる。
<br>
原理はこんな感じで例外が発生しているから。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3668884/4fad7d67-42ae-1e4f-550b-ee6da3c6788f.png)

考えられる対策は2つあって

・新規ウィンドウを開かない設計にする。
安全だが利便性が悪い。ただし、プロファイルを共有した別のexeでビルドする方法もある。
 もしくは認証後にリダイレクトするなどして一つのウィンドウで完結する仕様にする手もある。

・新規ウィンドウをすべて開いておく。
アプリ起動時に、使うかもしれないすべてのウィンドウを開き、非表示にして待機させる。

・if文で分岐する
やばい値が入力された際にif文で切り分けておいて、ダイアログかなんかで警告を出す。
楽しそうではある。

しらたまWPFブラウザはあくまでもサンプルなので、あえて放置する。

<h2>6.本ビルドしてみよう</h2>
ビルドには二種類あって、

**ビルドは早いけど遅いデバッグ用(Debug)** と **ビルドは時間がかかるが動作が早いリリース用(Release)** がある

今回はさらにAPIの内容も分岐するので4つもあるわけだが、基本
検証時は「Debug Stable APIs」
リリース時は「Release Stable APIs」
がいい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3668884/adaf8bec-ca2a-987f-9c9e-3737ae0b999d.png)
~~~
'Siratama WPF.exe' (CoreCLR: clrhost): 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.25\System.Reflection.Primitives.dll'
が読み込まれました。シンボルの読み込みをスキップしました。モジュールは最適化されていて、デバッグ オプションの [マイ コードのみ] 設定が有効になっています。
~~~
という風になんか最適化されてるせいか、ビルド速度は体感はあんま変わらない。


さて、ビルドしたやつはbinフォルダ内の底のほうに沈んでいる。
「Release Stable APIs」で一回ビルドしてからエクスプローラーで開く場合は
~~~
bin\Release Stable APIs\netcoreapp6.0-windows
~~~
にいるはず。

今回使うファイルは
~~~
2024/01/06  11:59    <DIR>          .
2024/01/06  11:56    <DIR>          ..
2024/01/06  11:56    <DIR>          assets
2023/10/31  17:33           703,960 Microsoft.Web.WebView2.Core.dll
2023/10/31  17:33            40,536 Microsoft.Web.WebView2.WinForms.dll
2023/10/31  17:33            48,200 Microsoft.Web.WebView2.Wpf.dll
2024/01/06  11:56    <DIR>          runtimes
2024/01/06  11:56             2,474 Siratama WPF.deps.json
2024/01/06  11:56           141,824 Siratama WPF.dll
2024/01/06  11:56           148,992 Siratama WPF.exe
2024/01/06  11:56            44,524 Siratama WPF.pdb
2024/01/06  11:56               372 Siratama WPF.runtimeconfig.json
               8 個のファイル           1,130,882 バイト
               4 個のディレクトリ  31,212,175,360 バイトの空き領域
~~~
だ。〇〇.exe.WebViewフォルダはランタイムが詰まっているので消していい。
(エクスプローラーのパスのところに'cmd' と入力し、コマンドプロンプトで'dir' するとこんな感じで出てくる)

<h2>7.本当に動く?</h2>

さて、開発環境ならまだしも、一般ユーザはこれを起動できるだろうか。
今回はWindows Sandboxで検証していく。

(Windows Sandboxは10以降のProライセンスが必要です。Homeの人はVirtualboxあたりでやりましょう。)

https://learn.microsoft.com/ja-jp/windows/security/application-security/application-isolation/windows-sandbox/windows-sandbox-overview

https://www.virtualbox.org/

Windows Sandboxではクリップボードが同じなのでコピペすれば持っていける。

Virtualboxなら共有ドライブなりGuestAddon入れるなりimgBurnでiso化して読み込ませるなりすればいい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3668884/3679eb42-b916-8a45-6611-d207cb012049.png)

Sandboxの場合こんな感じで怒られるかもしれない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3668884/ae2811c2-1f29-5b58-16eb-e11b2c1ce680.png)
これは.NETランタイムがないということなのだが、WPFである以上仕方がない。

Sandboxは純粋なWindowsだからないだけで、実際にアプリが使われる環境では
社内システムとかPCメーカーのアドウェ...謹製アプリの都合で最初から入ってるとは思う。

Yesを押せばインストールできるので、そうしよう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3668884/c93c9c8f-94f5-d580-ffc2-61e073454b53.png)

動いたら成功！
(もしもエラーが起こったなら、WindowsSandboxにWebView2ランタイムがなかっただけ。Windows10以降にはふつう入っているので問題はない)

<h1>まとめ</h1>

・WebView2にはいろんな機能がある。
・ウィンドウ呼び出しには注意。
・WindowsSandbox / Virtualbox でたまに見てみよう。
・マイナーバージョンごとにコードは**バックアップ**しておいて、障害発生時に振り返れるようにしよう！

<h1>次回へ続く</h1>

***未定。***