[.net framework] chromium web browser

久々にWindows.Formsです。本当は.net coreで作りたかったのだけど、WebBrowserコントロールがIE7なのな!さすがにEdgeだとは思っていないがIE11かと……。ということで埋め込みchromiumコントロールを使うことにした。これが.net core3.0ではどうにもこうにもエラーになるので、今回は.net framework 4.7.2で。

https://gist.github.com/dobusarai2016/9e3d179d8f5ac7fa46468b468d6e8616

マニフェスト追加して高DPI対応とかにもしてるけど、基本はこれだけ。ボタンとかはさすがに面倒なのでフォームデザイナでペタペタ。CefSharpはデザイナで貼るとバージョンが古いだのビルド時にようわからんエラー吐いたりだの鬱陶しいので直書き。

Application -> Chromiumは基本的にJavascriptを走らせることでDOM操作とか何でも出来るみたいだが、Chromium -> Application、例えばDOMの取得などはレンダリング時にしかできないっぽい。まー目的は片方向で良いので調べるのはやめた。生スレッド使うのはダセえとかは言うな。

※20191017 生スレッドの部分を修正

※20191017 LoadError(httpdが存在しないページで404を返すのではなく、サーバ自体に接続できない、存在しない場合は真っ白で終わり)時に、エラーhtmlを読み込んで描画するように変更

※20191017 DOM要素へのアクセスも試してみた。が、idやインデックスを指定しての取得は出来るが、複数の要素(getElementsByClassNameでまとめて取得)はdebuggerで見てもnullになってしまって取れないみたい。

        private async void ToolStripButton2_Click(object sender, EventArgs e)
        {
            if (!chromium.IsLoading)
            {
                //var js = "document.getElementsByClassName('chromium-test');"; // NG
                //var js = "document.getElementsByClassName('chromium-test')[0];"; // NG
                var js = "document.getElementsByClassName('chromium-test')[0].innerText;"; // OK
                //var js = "document.getElementById('user_id').value;"; // OK
                var test = "";
                await chromium.GetBrowser().MainFrame.EvaluateScriptAsync(js).ContinueWith(
                    x => {
                        var response = x.Result;
                        if(response.Success && response.Result != null)
                        {
                            test = response.Result.ToString();
                        }
                    }
                );
                StatusMessageLabel.Text = test;
            }
        }

https://www.dobusarai.net/env/