WebView2C# JavaScript와 협력

어제의 오늘이지만, 웹뷰2를 사용해 자바스크립트와 C#를 연합시키는 방법을 알게 되어 기사에 남게 되었습니다.
(필자 개인의 일이지만 큐타 기사는 오늘 사흘째 나온다(웃음)
오늘 일이 끝나서 편하게 기사를 쓰고 싶어요...(웃음)

부호화


어쨌든 먼저 샘플의 코드를 아래에 붙여 놓으세요.
Form1.cs 및 JavaScript가 포함된 Sample그래서 눈치가 빠른 사람이라면 샘플 코드만 봐도 충분하다.
(.}에 관해서는 아무렇게나 썼으니 너무 깊이 들어가지 마세요(웃음))
Form1.cs
using Microsoft.Web.WebView2.Core;
using Microsoft.Web.WebView2.WinForms;
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace SampleWebView2Form
{
    public partial class Form1 : Form
    {
        /// <summary>webviewのコントロール(わかりやすい様に、デザイナーを使わずにコード側で実装します。)</summary>
        private WebView2 WebView = new WebView2
        {
            //個人の環境に合わせて下さい
            Source = new Uri("file:///C:/Users/name/Desktop/sample.html"),
        };

        /// <summary>JavaScriptで呼ぶ関数を保持するオブジェクト</summary>
        private JsToCs CsClass = new JsToCs();

        public Form1()
        {
            this.Controls.Add(WebView);
            InitializeComponent();

            //WebView2のサイズをフォームのサイズに合わせる
            WebView.Size = this.Size;
            this.SizeChanged += Form1_SizeChanged;

            //WebView2のロード完了時のイベント
            WebView.NavigationCompleted += WebView_NavigationCompleted;
        }

        /// <summary>WebView2のロード完了時</summary>
        private void WebView_NavigationCompleted(object sender, CoreWebView2NavigationCompletedEventArgs e)
        {
            try
            {
                if (WebView.CoreWebView2 != null)
                {
                    //JavaScriptからC#のメソッドが実行できる様に仕込む
                    WebView.CoreWebView2.AddHostObjectToScript("class", CsClass);

                    //JavaScriptの関数を実行
                    CsToJs();
                }
                else MessageBox.Show("CoreWebView2==null");
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        /// <summary>Jsのメソッドを実行</summary>
        private async void CsToJs()
        {
            //WebView.ExecuteScriptAsync("func1()").ResultをするとWebView2がフリーズする
            string str1 = await WebView.ExecuteScriptAsync("func1(\"C#からの呼び出し\")");
            MessageBox.Show("Jsからの戻り値>" + str1);
        }

        /// <summary>サイズ変更時のイベントでWebView2のサイズをフォームに合わせる</summary>
        private void Form1_SizeChanged(object sender, EventArgs e)
        {
            WebView.Size = this.Size;
        }
    }

    //↓属性設定が無いとエラーになります
    /// <summary>WebView2に読み込ませるためのJsで実行する関数を保持させたクラス</summary>
    [ClassInterface(ClassInterfaceType.AutoDual)]
    [ComVisible(true)]
    public class JsToCs
    {
        public void MessageShow(string strText)
        {
            MessageBox.Show("Jsからの呼び出し>" + strText);
        }
    }
}
sample.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta content="text/html;charset=utf-8" http-equiv="Content-Type" />
    <script language="javascript" type="text/javascript">
        //C#から呼び出すための関数
        function func1(str1) {
            alert("C# called>" + str1);
            return "success"
        }
        function ButtonClick() {
            //C#の関数の実行
            chrome.webview.hostObjects.class.MessageShow("Js send text");
        }
    </script>
</head>
<body>
    <h1>sample</h1>
    <input type="button" value='send Message' onclick="ButtonClick();"/>
    <script></script>
</body>
</html>

해설


C#->JavaScriptExecuteScriptAsync()를 사용하여 C#에서 JavaScript 내 함수를 호출합니다.이 함수는 며칠 전에 쓴 글에서 ExecuteScriptAsync("alert(\"message\")"); 방법을 사용했는데, 매개 변수의 내용을 자바스크립트로 처리할 수 있다면 자바스크립트 코드에서 혼자 만든 함수로 실행할 수도 있다.
주의점: ExecuteScriptAsync()Task이므로 반환값을 받을 때.Result 또는 await를 사용하지만 .Result를 사용하면 작동이 멈추고 처리가 불가능하므로 반환값을 얻으려면 await를 사용해야 합니다.
샘플 코드 중 아래 부분은 일치하는 곳입니다.
Form1.cs
        /// <summary>Jsのメソッドを実行</summary>
        private async void CsToJs()
        {
            //WebView.ExecuteScriptAsync("func1()").ResultをするとWebView2がフリーズする
            string str1 = await WebView.ExecuteScriptAsync("func1(\"C#からの呼び出し\")");
            MessageBox.Show("Jsからの戻り値>" + str1);
        }
sample.html
    <script language="javascript" type="text/javascript">
        //C#から呼び出すための関数
        function func1(str1) {
            alert("C# called>" + str1);
            return "success"
        }
    </script>
행위는 다음과 같다.
• 로드 즉시 JavaScript 경고 출력

• 경보 종료 후 정보상자 출력

JavaScript->C#
JavaScript에서 C#을 호출할 때 AddHostObjectToScript()를 사용하여 C#에서 만든 함수를 JavaScript에 읽어들입니다.WebMessageReceived 사용하는 방법도 있는 것 같은데 궁금하신 분들은 조사해주세요)
샘플 코드 중 아래 부분은 일치하는 곳입니다.
Form1.cs
        /// <summary>JavaScriptで呼ぶ関数を保持するオブジェクト</summary>
        JsToCs CsClass = new JsToCs();
        //JavaScriptからC#のメソッドが実行できる様に仕込む
        WebView.CoreWebView2.AddHostObjectToScript("class", CsClass);

//~~~一部省略~~~
    /// <summary>WebView2に読み込ませるためのJsで実行する関数を保持させたクラス</summary>
    [ClassInterface(ClassInterfaceType.AutoDual)]
    [ComVisible(true)]
    public class JsToCs
    {
        public void MessageShow(string strText)
        {
            MessageBox.Show("Jsからの呼び出し>" + strText);
        }
    }
sample.html
    <script language="javascript" type="text/javascript">
        function ButtonClick() {
            //C#の関数の実行
            chrome.webview.hostObjects.class.MessageShow("Js send text");
        }
    </script>

<body>
    <input type="button" value='send Message' onclick="ButtonClick();"/>
</body>
비헤이비어로서 브라우저에서 "send Message"를 누르면 C# 정보가 출력됩니다.

총결산


이번에는 이런 곳이야.
WebView2에 대한 기사는 어제 JavaScript에서 C# 처리를 시작하여 최근 일주일 동안 놓아두었는데, 그 문제가 해결되어 정말 다행입니다.
오늘은 특별히 쓸 게 없어요. (없어도 괜찮아요.(웃음)
제가 먼저 어제 쓴 기사의 링크를 붙이겠습니다.
https://qiita.com/NagaJun/items/4925a63ce7b93b80639e
끝까지 읽어주셔서 감사합니다.

좋은 웹페이지 즐겨찾기