天天看点

WinForm完美实现Cefsharp-v73.1控件C#与JS交互,并且可加载运行flash。

之前写过一篇Cefsharp-v49控件C#与JS交互的文章,在开发的同时也对Cefsharp-v73.1新版本也有一定了解,比较新的版本的使用相比于Cefsharp-v49还是有一定差异所以写篇文章记录一下。

旧版本Cefsharp-v49.1控件C#与JS交互请参考《WinForm完美实现Cefsharp-v49.1控件C#与JS交互,并且可加载运行flash。》

一:插件的下载及环境配置

在项目解决方案下右击——》管理NuGet程序包(N)...——》在浏览中输入Cefsharp——》选中Cefsharp.WinForms,然后在版本中选择73.1.130点击安装,安装完成后重启VS编辑器。

WinForm完美实现Cefsharp-v73.1控件C#与JS交互,并且可加载运行flash。
WinForm完美实现Cefsharp-v73.1控件C#与JS交互,并且可加载运行flash。

重启项目后打开当前解决方案下应用会多出下面几个引用,说明插件安装成功了,剩下的步骤及开发程序和旧版本控件大同小异需要注意的是(3.1:首先Cefsharp 控件注册申明JS对象)C#注册JS调用对象接口改变,

WinForm完美实现Cefsharp-v73.1控件C#与JS交互,并且可加载运行flash。

二:Cefsharp 控件设置加载缓存Cookie及支持flash插件

// On Win10 this will create a directory in AppData.
            var cache = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), System.IO.Path.Combine("MyApplication", "cache")); //cache缓存路径
            if (!System.IO.Directory.Exists(cache)) //判断cache文件是否存在
                System.IO.Directory.CreateDirectory(cache); //如果没有则创建cache缓存文件
            // Set the CachePath during initialization.
            var settings = new CefSettings() { CachePath = cache };
            //Cefsharp支持运行flash
            settings.CefCommandLineArgs["enable-system-flash"] = "1"; //启用flash
            settings.CefCommandLineArgs.Add("ppapi-flash-version", "32.0.0.171"); //设置flash插件版本
            settings.CefCommandLineArgs.Add("ppapi-flash-path", @"pepflashplayer.dll"); //使用指定的flash插件,不使用系统安装的flash版本
            Cef.Initialize(settings);
            // Create a browser component
            chromeBrowser = new ChromiumWebBrowser("http://localhost/index.html"); //本地测试url地址
            // Add it to the form and fill it to the form window.
            this.Controls.Add(chromeBrowser);
            chromeBrowser.Dock = DockStyle.Fill;
           

2.1:在运行项目加载 http://localhost/index.html 地址的时候需要先在本地下载部署nginx环境,把对应index.html 文件放到\nginx-1.19.10\html目录下然后运行nginx服务,否则会出现无法加载的问题。nginx 相关下载及环境配置本文不再做详细介绍。

三:JS调用C#

3.1:首先Cefsharp 控件注册申明JS对象(JS调用C#所需对象及接口)

//Replaced with
            CefSharpSettings.LegacyJavascriptBindingEnabled = true;
            //注册JS对象cefAsyncJS,_Event中方法为JS实际调用方法。示例:cefAsyncJS.login("");
            chromeBrowser.JavascriptObjectRepository.Register("cefAsyncJS", new _Event(), isAsync: true, options: BindingOptions.DefaultBinder);


        public class _Event
        {
            public void login(string _data)
            {
                MessageBox.Show(_data);
            }

            public void payment(string _data)
            {
                MessageBox.Show("这是C#的MessageBox窗口,收到了JS的调用,参数:" + _data);
            }
        }
           

2:完成3.1步骤注册好JS对象后接下来我们来写 JS调用C#代码

var data = "JS调用C#登录接口";
cefAsyncJS.login(data);
           

完成上面两步后就可以实现JS调用C#接口,效果如下:

WinForm完美实现Cefsharp-v73.1控件C#与JS交互,并且可加载运行flash。

四:C#调用JS

4.1:Cefsharp 控件C#调用回传JS

string result = string.Empty;
            string account = "account";
            string userId = "userId";
            string token = "token";
            //C#调用JS //MG_CallBack方法
            chromeBrowser.GetMainFrame().ExecuteJavaScriptAsync(String.Format($"MG_CallBack('{account}', '{userId}', '{token}')", result));
           

4.2:JS接收C#回调

function MG_CallBack(account, userId, token) {
			alert("接收C#调用JS登陆监听,回传参数:account=" + account + ", userId=" + userId + ", token=" + token);

			document.getElementById("sdkmsg").innerHTML = "<br>用户名:" + userId
				+ "<br>token:" + token + "<br>account:" + account;
			//拿到userId,token两个参数及appKey,去mg服务器验证该用户的登录状态。若返回200,则表明登录成功
			//验证登录状态一般是在服务器端实现(即在此处向cp服务器发验证请求,然后由cp服务器向mg服务器发验证请求,然后由cp服务器返回此处)

			//验证成功后,实现cp游戏内部用户的登录(注册),此步可以与上一步合并,由cp服务器向mg服务器发验证请求后处理。

			//登录成功后,游戏处理						
		}
           

完成上面两步后可实现C#调用JS接口,效果如下:

WinForm完美实现Cefsharp-v73.1控件C#与JS交互,并且可加载运行flash。

五:当前线程不在单线程单元中错误处理方案

因为我们的项目是SDK登录支付项目在JS调用C# login接口后执行调用 SDK登录接口唤起登录框的时候提示:当前线程不在单线程单元中,因此无法实例化 activex 控件“8856f961-340a-11d0-a96 ,本来之前Cefsharp 加载flash插件以及C#JS相互调用的问题卡了好久处理好以后激动的不行感觉以为完事儿了呢,谁知道又碰到一个线程的问题,为了解决这个问题又卡了好久~好久~,最终搞定了分享给大家以下是处理方案:

public void login(string _data)
            {
                MessageBox.Show(_data);

                //修复调用SDK登录提示当前线程不在单线程单元中错误
                Thread t1 = new Thread(ThreadLogin);
                t1.SetApartmentState(ApartmentState.STA);
                t1.Start();
                //修复调用SDK登录提示当前线程不在单线程单元中错误
            }


        static void ThreadLogin()
        {
            //调用SDK登录接口
        }
           

六:最后是项目源码下载地址

https://download.csdn.net/download/zhao331863874/19265898

继续阅读