Приложение WPF аварийно завершает работу после переопределения CefApp.GetRenderProcessHandler() для вызова из JS в C#
Я разрабатываю приложение wpf с использованием Xilium.CefGlue и Xilium.CefGlue.WPF. Мое приложение WPF аварийно завершает работу после реализации Xilium.CefGlue.CefApp.GetRenderProcessHandler() в SampleCefApp. До этой реализации приложение работало нормально без сбоев. На самом деле мне нужно вызвать функцию C# из HTML-локальной страницы с помощью функции JavaScript. Эта функция работает нормально в 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>
Есть ли какие-либо проблемы для libcef dll при работе с 64 бит. Кто-нибудь может помочь для реализации вызова JS в C# с помощью Xilium.CefGlue и Xilium.CefGlue.WPF. Следующий ссылочный код, который я использую для этого по ссылке https://groups.google.com/forum/
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));
}
Любая помощь приветствуется.
1 ответ
Я включил ведение журнала cef. Он показывает следующий журнал [0826/171951: ОШИБКА:proxy_service_factory.cc(128)] Невозможно использовать преобразователь прокси-сервера V8 в режиме одного процесса. Так что я изменил SingleProcess=false в CeffSetting. Теперь проблема сбоев решена и запрошенная веб-страница не отображается в cefwpfbrowser. Теперь я получаю следующее сообщение из файла журнала [0826/173636:VERBOSE1:pref_proxy_config_tracker_impl.cc(151)] 000000001B2A7CC0: установить службу конфигурации прокси-сервера Chrome на 000000001B234F60 [0826/173636:VERBOSE1:pref_cc0.002: 276006): pref_pro0. Завершено отправка прокси в UpdateProxyConfig [0826/173637:VERBOSE1:webrtc_internals.cc(85)] Не удалось получить каталог для загрузки. Как решить проблему с загрузкой запрошенной страницы в cefwpfbrowser.