您的位置:

深入解析cefsharp.browsersubprocess

一、什么是cefsharp.browsersubprocess

cefsharp.browsersubprocess是Chromium Embedded Framework(CEF)的一部分,是Chromium内核的一个子进程,主要用于处理CEF应用程序中的浏览器功能。它是cefsharp浏览器控件的核心组成部分之一,控件本身可以显示网页,但必须通过浏览器子进程才能实现交互。

CEF本身是一个开源项目,旨在为C++应用程序提供嵌入式Chromium浏览器功能。cefsharp是它的一个.NET封装,使得开发人员可以在.NET中使用CEF的功能。它提供了一个名为CefSharp.WinForms.ChromiumWebBrowser的WinForms控件,使得用户可以在应用程序中嵌入并显示一个Chromium浏览器。

二、cefsharp.browsersubprocess的作用

cefsharp.browsersubprocess的主要作用是为CEF应用程序中的浏览器提供支持。因为CEF浏览器控件本身并不包含浏览器引擎,它需要与浏览器子进程进行通信以实现基本的浏览器功能。浏览器子进程在CEF应用程序中起着至关重要的作用。

浏览器子进程主要包括以下功能:

  • 网络请求:浏览器进程通过IPC(inter-process communication,进程间通信)向子进程发送请求,子进程负责执行这些请求并返回结果。子进程还会处理Cookie、缓存、TLS证书等网络相关的任务。
  • JavaScript执行:浏览器进程将JavaScript代码传递给子进程执行,并接收代码执行的结果。子进程的JavaScript执行环境与浏览器进程不同,在子进程的JavaScript执行环境中,不能使用访问浏览器DOM、CSS的API,但是可以访问CEF的API。
  • 浏览器渲染:子进程负责渲染网页,并将渲染后的内容传递给浏览器进程显示。CEF使用Chromium作为底层渲染引擎,子进程中使用的就是Chromium底层的渲染引擎。

三、如何使用cefsharp.browsersubprocess

使用cefsharp.browsersubprocess,需要先安装cefsharp NuGet程序包。

Install-Package CefSharp.WinForms

在使用CefSharp的WinForms控件之前,需要在应用程序的入口点中先初始化CEF:

    static void Main()
    {
        Cef.EnableHighDPISupport();
        CefSettings settings = new CefSettings();
        settings.CachePath = "cache";
        Cef.Initialize(settings);

        // ...

        Cef.Shutdown();
    }

定义一个CefSharp.WinForms.ChromiumWebBrowser控件,设置它的Dock属性:

    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();

            ChromiumWebBrowser browser = new ChromiumWebBrowser("https://www.google.com");
            browser.Dock = DockStyle.Fill;
            this.Controls.Add(browser);
        }
    }

四、如何与cefsharp.browsersubprocess进行交互

CEF应用程序中,浏览器进程与浏览器子进程使用IPC进行通信。在CEF中,IPC有两种实现方式:Chrome IPC和Basic IPC。

Chrome IPC是基于Google Chrome浏览器的IPC实现,也是默认的实现方式。使用Chrome IPC需要调用以下代码:

    CefSharpSettings.LegacyJavascriptBindingEnabled = true;
    browser.RegisterAsyncJsObject("external", new ExternalObject(), false);

其中,ExternalObject是对浏览器进程与子进程之间的通信进行了封装,它实现了一些JSBridge的功能。在应用程序中,可以使用这个类定义一个对象,然后通过注册这个对象的方式,在浏览器进程和子进程之间建立通信。

例如,我们在应用程序中定义了一个名为“Interop”的对象,代码如下:

public class Interop
{
    public void DoSomething(string arg)
    {
        MessageBox.Show(arg);
    }
}

然后,在注册这个对象时,需要指定在浏览器JavaScript中调用这个对象时的名称:

browser.RegisterAsyncJsObject("interop", new Interop());

在JavaScript代码中,通过外部对象“interop”即可调用定义好的“Interop”对象中的方法:

Interop.DoSomething("Hello World!");

五、如何调试cefsharp.browsersubprocess

CEF提供了一套调试工具,可用于调试CEF应用程序中的浏览器进程和浏览器子进程。需要首先开启CEF的Debug模式,在初始化CEF的Settings参数中设置以下参数:

settings.LogFile = "cef.log";
settings.LogSeverity = LogSeverity.Verbose;
settings.RemoteDebuggingPort = 20480;
settings.RemoteDebuggingPipeName = "cefsharp_debug";

其中,RemoteDebuggingPort是Debug的端口号,设置RemoteDebuggingPipeName是为了避免浏览器启动多次导致调试端口被占用的问题。

在CEF应用程序中,启用调试器的方法是,在启动应用程序时,指定程序的命令行参数:

    static void Main(string[] args)
    {
        Cef.EnableHighDPISupport();

        CefSettings settings = new CefSettings();
        settings.CachePath = "cache";
        settings.LogFile = "cef.log";
        settings.LogSeverity = LogSeverity.Verbose;
        settings.RemoteDebuggingPort = 20480;
        settings.RemoteDebuggingPipeName = "cefsharp_debug";
        Cef.Initialize(settings);

        if (args.Contains("--debug"))
        {
            MainForm form = new MainForm();
            form.Show();

            Cef.DoMessageLoopWork();
            Application.Run();
        }
        else
        {
            // ...
        }

        Cef.Shutdown();
    }

然后,在浏览器进程中,可以打开Chrome浏览器,输入以下地址:

chrome://inspect/

点击“Open dedicated DevTools for Node”按钮,即可打开调试器。