Xilium.CefGlue如何用返回值执行JavaScript?

时间:2013-08-14 07:05:11

标签: c# javascript google-chrome-devtools

我是编程多线程的新手,我无法从xelium示例中了解如何执行javascript并获取返回值。 我测试过:

browser.GetMainFrame().ExecuteJavaScript("SetContent('my Text.')", null, 0);

执行了javascript,但我这个函数不允许我获取返回值。 我应该执行以下函数来获取用户在框中写的所有文本..

browser.GetMainFrame().ExecuteJavaScript("getContent('')", null, 0);

函数TryEval应该这样做......

browser.GetMainFrame().V8Context.TryEval("GetDirtyFlag", out returninformation , out exx);

但是这个函数不能从浏览器中调用,我认为必须从渲染器中调用它?我怎么能这样做?

我无法理解有关CefRenderProcessHandlerOnProcessMessageReceived的解释。如何注册脚本对象并设置我的javascript&参数Δ

如果有任何建议我可以解决这个问题!

3 个答案:

答案 0 :(得分:3)

我一直在努力解决这个问题。我认为没有办法同步这样做......或者很容易:)

也许可以做到的是:

  1. 从浏览器中将sendProcessMessage与所有JS信息一起发送到渲染器 处理。您可以以结构化的方式将所有类型的参数传递给此调用,因此按顺序封装JS方法名称和params并不困难。
  2. 在渲染器进程(RenderProcessHandler onProcessMessageReceived方法)中对V8Context执行TryEval并通过out参数获取返回值,并将sendProcessMessage返回给 具有JS返回值的浏览器进程(请注意,这支持JS方法中的普通返回语义)。您在onProcessMessageReceived中获取浏览器实例引用,因此它就像这样(混合伪代码)

    browser.GetMainFrame()。CefV8Context.tryEval(js-code,out retValue,out exception);

    处理retValue;

    browser.sendProcessMessage(...);

  3. 浏览器将在onProcessMessageReceived中的WebClient中获得回调。

    在设置JS方面没有什么特别之处。我有一个加载的html页面,里面有一个js函数。它需要一个参数作为输入并返回一个字符串。在tryEval的js-code参数中我只提供了这个值:

    "myJSFunctionName('here I am - input param')"
    

    这有点令人费解,但看起来像一个简洁可行的方法 - 比在我的视图中执行自定义处理程序的ExecuteJavaScript和通过XHR发布结果更好。

    我尝试了这个并且它确实工作得很好....并且并不坏,因为它都是非阻塞的。需要完成浏览器过程中的连线以正确处理响应。

    这可以扩展并构建到一组类中,以便为各种调用抽象出来。

    看看Xilium演示应用。大多数必要的布线已经存在于onProcessMessage中 - 进行全局搜索。寻找

    1. DemoRendererProcessHandler.cs - 渲染器端,这是您将调用tryEval的位置
    2. DemoApp.cs - 这是浏览器端,查找sendProcessMessage - 这将启动您的JS调用过程。
    3. WebClient.cs - 这是浏览器端。在这里,您将从渲染器接收来自JS
    4. 的返回值的消息

      干杯。

答案 1 :(得分:1)

我通过对自定义方案处理程序的ajax调用将我的JavaScript函数的结果值返回给Xilium主机应用程序来解决了这个问题。根据Xilium的作者fddima,它是the easiest way to do IPC

您可以在the Xilium's demo app中找到如何实现方案处理程序的示例。

答案 2 :(得分:-4)

查看此帖子:https://groups.google.com/forum/#!topic/cefglue/CziVAo8Ojg4

using System;
using System.Windows.Forms;
using Xilium.CefGlue;
using Xilium.CefGlue.WindowsForms;

namespace CefGlue3
{
  public partial class Form1 : Form
  {
    private CefWebBrowser browser;

    public Form1()
    {
      InitializeCef();
      InitializeComponent();
    }

    private static void InitializeCef()
    {
      CefRuntime.Load();
      CefMainArgs cefArgs = new CefMainArgs(new[] {"--force-renderer-accessibility"});
      CefApplication cefApp = new CefApplication();
      CefRuntime.ExecuteProcess(cefArgs, cefApp);
      CefSettings cefSettings = new CefSettings
      {
        SingleProcess = false, 
        MultiThreadedMessageLoop = true, 
        LogSeverity = CefLogSeverity.ErrorReport, 
        LogFile = "CefGlue.log",
      };
      CefRuntime.Initialize(cefArgs, cefSettings, cefApp);
    }

    private void Form1_Load(object sender, EventArgs e)
    {
      browser = new CefWebBrowser
      {
        Visible = true,
        //StartUrl = "http://www.google.com",
        Dock = DockStyle.Fill,
        Parent = this
      };
      Controls.Add(browser);
      browser.BrowserCreated += BrowserOnBrowserCreated;
    }

    private void BrowserOnBrowserCreated(object sender, EventArgs eventArgs)
    {
      browser.Browser.GetMainFrame().LoadUrl("http://www.google.com");
    }
  }
}

using Xilium.CefGlue;

namespace CefGlue3
{
  internal sealed class CefApplication : CefApp
  {
    protected override CefRenderProcessHandler GetRenderProcessHandler()
    {
      return new RenderProcessHandler();
    }
  }

  internal sealed class RenderProcessHandler : CefRenderProcessHandler
  {
    protected override void OnWebKitInitialized()
    {
      CefRuntime.RegisterExtension("testExtension", "var test;if (!test)test = {};(function() {test.myval = 'My Value!';})();", null);
      base.OnWebKitInitialized();
    }
  }
}