WPF应用程序在重写CefApp.GetRenderProcessHandler()以使JS调用c#后崩溃

本文关键字:JS 以使 调用 崩溃 应用程序 重写 CefApp GetRenderProcessHandler WPF | 更新日期: 2023-09-27 18:03:59

我正在使用Xilium开发一个wpf应用程序。CefGlue和Xilium.CefGlue.WPF。在SampleCefApp中实现Xilium.CefGlue.CefApp.GetRenderProcessHandler()后,我的WPF应用程序崩溃了。在此实现之前,应用程序运行良好,没有任何崩溃。实际上,我需要通过javascript函数从html本地页面调用c#函数。此功能在32位版本中可以正常工作,但在64位版本中不行。以下是我的实现。

internal sealed class SampleCefApp : CefApp
{
    public SampleCefApp()
    {
    }
    private CefRenderProcessHandler renderProcessHandler = new Views.DemoRenderProcessHandler();
    protected override CefRenderProcessHandler GetRenderProcessHandler()
    {
        return renderProcessHandler;
    }
}

显示应用程序崩溃的消息

<ProblemSignatures>
    <EventType>APPCRASH</EventType>
    <Parameter0>StreetMap.vshost.exe</Parameter0>
    <Parameter1>14.0.23107.0</Parameter1>
    <Parameter2>559b788a</Parameter2>
    <Parameter3>libcef.DLL</Parameter3>
    <Parameter4>3.2743.1449.0</Parameter4>
    <Parameter5>57bbfe66</Parameter5>
    <Parameter6>80000003</Parameter6>
    <Parameter7>0000000000b68267</Parameter7>
</ProblemSignatures>

在64位工作时libcef dll是否有任何问题?任何人都可以使用Xilium帮助实现JS到c#的调用。CefGlue和Xilium.CefGlue.WPF。下面的参考代码,我正在使用这从链接https://groups.google.com/forum/!主题/cefglue EhskGZ9OndY

using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Threading;
using System;
namespace Xilium.CefGlue.Client {
    internal sealed class DemoApp: CefApp {
        private CefRenderProcessHandler renderProcessHandler = new DemoRenderProcessHandler();
        protected override CefRenderProcessHandler GetRenderProcessHandler() {
            return renderProcessHandler;
        }
    }
    internal class DemoRenderProcessHandler: CefRenderProcessHandler {
        MyCustomCefV8Handler myCefV8Handler = new MyCustomCefV8Handler();
        protected override void OnWebKitInitialized() {
            base.OnWebKitInitialized();
            var nativeFunction = @ "nativeImplementation = function(onSuccess) {
            native
            function MyNativeFunction(onSuccess);
            return MyNativeFunction(onSuccess);
        };
        ";
        CefRuntime.RegisterExtension("myExtension", nativeFunction, myCefV8Handler);
    }
    internal class MyCustomCefV8Handler: CefV8Handler {
        protected override bool Execute(string name, CefV8Value obj, CefV8Value[] arguments, out CefV8Value returnValue,
            out string exception) {
            //Debugger.Launch();
            var context = CefV8Context.GetCurrentContext();
            var taskRunner = CefTaskRunner.GetForCurrentThread();
            var callback = arguments[0];
            new Thread(() => {
                //Sleep a bit: to test whether the app remains responsive
                Thread.Sleep(3000);
                taskRunner.PostTask(new CefCallbackTask(context, callback));
            }).Start();
            returnValue = CefV8Value.CreateBool(true);
            exception = null;
            return true;
        }
    }
    internal class CefCallbackTask: CefTask {
        private readonly CefV8Context context;
        private readonly CefV8Value callback;
        public CefCallbackTask(CefV8Context context, CefV8Value callback) {
            this.context = context;
            this.callback = callback;
        }
        protected override void Execute() {
            var callbackArguments = CreateCallbackArguments();
            callback.ExecuteFunctionWithContext(context, null, callbackArguments);
        }
        private CefV8Value[] CreateCallbackArguments() {
            var imageInBase64EncodedString = LoadImage(@ "C:'hamb.jpg");
            context.Enter();
            var imageV8String = CefV8Value.CreateString(imageInBase64EncodedString);
            var featureV8Object = CefV8Value.CreateObject(null);
            var listOfFeaturesV8Array = CefV8Value.CreateArray(1);
            featureV8Object.SetValue("name", CefV8Value.CreateString("V8"), CefV8PropertyAttribute.None);
            featureV8Object.SetValue("isEnabled", CefV8Value.CreateInt(0), CefV8PropertyAttribute.None);
            featureV8Object.SetValue("isFromJSCode", CefV8Value.CreateBool(false), CefV8PropertyAttribute.None);
            listOfFeaturesV8Array.SetValue(0, featureV8Object);
            context.Exit();
            return new [] {
                listOfFeaturesV8Array,
                imageV8String
            };
        }
        private string LoadImage(string fileName) {
            using(var memoryStream = new MemoryStream()) {
                var image = Bitmap.FromFile(fileName);
                image.Save(memoryStream, ImageFormat.Png);
                byte[] imageBytes = memoryStream.ToArray();
                return Convert.ToBase64String(imageBytes);
            }
        }
    }
}

首先加载的HTML文件:

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta charset="utf-8" />
        <title>C# and JS experiments</title>
        <script src="index.js"></script>
    </head>
    <body>
        <h1>C# and JS are best friends</h1>
        <div id="features"></div>      
        <div id="image"></div>
    </body>
</html>
JavaScript代码
function Browser() {
}
Browser.prototype.ListAllFeatures = function(onSuccess) {
    return nativeImplementation(onSuccess);
}
function App(browser) {
    this.browser = browser;
}
App.prototype.Run = function() {
    var beforeRun = new Date().getTime();
    this.browser.ListAllFeatures(function(features, imageInBase64EncodedString) {
        var feautersListString = '';
        for (var i = 0; i < features.length; i++) {
            var f = features[i];
            feautersListString += ('<p>' + 'Name: ' + f.name + ', is enabled: ' + f.isEnabled + ', is called from js code: ' + f.isFromJSCode + '</p>');
        }
        feautersListString += '<p> The image: </p>';
        feautersListString += '<p>' + imageInBase64EncodedString + '</p>';
        document.getElementById("features").innerHTML = feautersListString;
        var afterRun = new Date().getTime();
        document.getElementById("image").innerHTML = '<img src="data:image/png;base64,' + imageInBase64EncodedString + '" />';
        var afterLoadedImage = new Date().getTime();
        console.log("ELAPSED TIME - INSIDE LIST ALL FEATURES: " + (afterRun - beforeRun));
        console.log("ELAPSED TIME - IMAGE IS LOADED TO THE <img> TAG: " + (afterLoadedImage - beforeRun));
    });
}
window.onload = function() {
    var browser = new Browser();
    var application = new App(browser);
    //Lets measure
    var beforeRun = new Date().getTime();
    application.Run();
    var afterRun = new Date().getTime();
    console.log("ELAPSED TIME - INSIDE ONLOAD: " + (afterRun - beforeRun));
}

WPF应用程序在重写CefApp.GetRenderProcessHandler()以使JS调用c#后崩溃

我启用了cef日志记录。它显示了以下日志[0826/171951:ERROR:proxy_service_factory.cc(128)]无法在单进程模式下使用V8代理解析器。所以我改变了CeffSetting中的SingleProcess=false。现在崩溃问题解决了,然后请求的网页不显示在cefwpfbrowser。现在我从日志文件中得到以下消息[0826/173636:VERBOSE1:pref_proxy_config_tracker_impl.cc(151)] 000000001B2A7CC0:设置chrome代理配置服务为000000001B234F60[0826/173636:VERBOSE1:pref_proxy_config_tracker_impl.cc(276)] 000000001B2A7CC0:完成向UpdateProxyConfig推送代理[0826/173637:VERBOSE1:webrtc_internal .cc(85)]无法获取下载目录。如何解决cefwpfbrowser中请求的页面未加载问题。