新しもの好きプログラマの耳より情報ブログ

仕事でもあるプログラミングについて役に立ちそうな情報を発信していこうというブログです。役に立たなそうな情報はfacebookで。

WPFのWebView2が実行環境で表示されない場合、exeがあるフォルダに実行ユーザーの書き込み権限が無いのが問題かも

概要

WPFの画面にWebView2を実装。デバッグ実行すると問題ないが、実行環境にインストールすると表示されない・・・?

そういう場合、WebView2はexeがあるフォルダへの書き込み権限を要求するという特徴のせいかもしれません。その説明と解決策です。

最初に結論まとめ

  • WebView2のインスタンスに、下記※1のように設定して、確実に書き込み権限があるフォルダを使わせるようにしましょう。
  • 処理に時間がかかること、処理が終わるまでWebView2を使用できない(Sourceを与えたりしてはいけない)という点に注意です。

※1

//xaml側でName="webView"と定義している前提です
var webViewUserDataFolder = @"<このexe専用の、ユーザーが書き込み可能なフォルダのフルパス>";
var cwv2Environment = await CoreWebView2Environment.CreateAsync(null, webViewUserDataFolder, new CoreWebView2EnvironmentOptions());
await webView.EnsureCoreWebView2Async(cwv2Environment);

説明と解決方法

実行環境にインストールすると、WebView2コントロールだけが表示されない。例外やメッセージが出たり異常終了するわけでもなく、ただ表示されないだけ。こんな現象に出会って、解析に手間取りました。

そういう場合、WebView2を実装しているexeファイルのインストール先に、実行ユーザーの書き込み権限があるかを確認しましょう。

実行はできるが書き込み権限が無いというのは、意外にあり得るケースです。例えば、インストーラで管理者権限を使ってProgram Filesへインストールしたexeを、UAC昇格せずにユーザーが実行する場合、書き込み権限が無い状態になります。

なぜその権限が必要かというと、WPF向けWebView2がデフォルトでは、実装されたexeと同じフォルダにデータファイルを作ろうとするためです。

こうした場合、exeから確実に書き込み可能なフォルダを、データファイル作成用の場所として与えてやる必要があります。例えばそのユーザーのTempフォルダ等です。

WebView2のインスタンスを生成してから、最初に次のようにすることで設定できます。この例では、Tempの下の「MyExeFolder」というこのexe固有のフォルダを与える例としました。

var webViewUserDataFolder = Environment.ExpandEnvironmentVariables(@"%Temp%\MyExeFolder");
var cwv2Environment = await CoreWebView2Environment.CreateAsync(null, webViewUserDataFolder, new CoreWebView2EnvironmentOptions());
await webView.EnsureCoreWebView2Async(cwv2Environment);

WebView2を動かしてから(例えばSourceを設定してから)変更することはできないので、処理順序に注意しましょう。WPFのウインドウに置く場合、Window.Loadedなどのタイミングで最初に処理してしまうのが良いと思います。

またawaitが入っているところからも見て取れると思いますが、処理に時間がかかるという点にも注意です。「最初はWebView2部分が非表示で、処理が終わり次第表示される」という動きで良ければ上記のように単純な呼び出しで良いですが、「表示されるまでの間はプログレスバーを出すなど動きを変える」といった場合は呼び出し箇所や順序に一工夫が必要になると思います。

まとめ

普通のコントロールと同じ感覚でWebView2をWPFの画面上で使ったら、デバッグ実行では気づけないような意外な落とし穴がありました。使う機会があったら思いだしてみてください。