个性化阅读
专注于IT技术分析

如何在Winforms应用程序中使用CefSharp(Chrome嵌入式框架c#)

本文概述

CefSharp是将功能完善的标准投诉网络浏览器嵌入到C#或VB.NET应用程序中的最简单方法。 CefSharp具有用于WinForms和WPF应用程序的浏览器控件, 以及用于自动化项目的无头(屏幕外)版本。 CefSharp基于Chromium Embedded Framework(Chrome浏览器的开源版本)。你可以在官方主页上获得有关CefSharp项目的更多信息。

你可以将CefSharp用作浏览器组件, 而不必取决于用户在Windows上安装的Internet Explorer的版本, 也可以将其用作应用程序的预定义用户界面。是的, 你可以在winforms c#应用程序中使用HTML控件(按钮, 输入), 并根据需要使用CSS进行自定义(Bootstrap等)。

这是你使用HTML, Javascript和CSS制作漂亮的本机Windows应用程序的机会, 让我们开始吧。

在本文中, 我们将使用49.0的CefSharp版本, 如果你想使用+51的CefSharp版本, 我们将提供一些新版本需要了解的技巧。

要求

  • 带NuGet软件包管理器的Visual Studio(> = 2010)。

1)创建一个基本的Winforms应用并使用NuGet包添加CefSharp

像往常一样创建一个Winforms应用程序, 然后以最新版本的.NET Framework为目标, 没有困难不是吗?在进行操作之前, 请确保你的机器已安装:

  • CefSharp 45.0和更高版本要求安装VC 2013可再发行组件包x86。
  • 早期版本需要VC 2012可再发行组件包x86。

否则, 你会发现以下错误:

An unhandled exception of type 'System.IO.FileNotFoundException' occurred in browser.exe Additional information: Could not load file or assembly 'CefSharp.Core.dll' or one of its dependencies.

现在, 在创建之后, 添加CefSharp。要添加CefSharp, 请转到Visual Studio右上角的解决方案资源管理器, 然后右键单击你的应用程序(在解决方案下方), 然后选择”管理NuGet程序包”。

CefSharp金块包装经理

当出现搜索菜单时, 键入cefsharp, 选择WinForms发行版并安装它。

与Visual Studio的每个版本一样, 界面可能有所不同, 只需确保安装位于nuget.org包源中的CefSharp发行的CefSharp.WinForms发行版, 在本示例中, 我们使用的是Visual Studio 2015

CefSharp NuGet软件包

遵循安装设置(接受热安装)。在安装过程中, 你应该在控制台中看到有关该过程的相关信息:

Attempting to gather dependency information for package 'CefSharp.WinForms.49.0.1' with respect to project 'embebbedChromium', targeting '.NETFramework, Version=v4.5.2'
Attempting to resolve dependencies for package 'CefSharp.WinForms.49.0.1' with DependencyBehavior 'Lowest'
Resolving actions to install package 'CefSharp.WinForms.49.0.1'
Resolved actions to install package 'CefSharp.WinForms.49.0.1'
  GET https://api.nuget.org/packages/cef.redist.x64.3.2623.1401.nupkg
  OK https://api.nuget.org/packages/cef.redist.x64.3.2623.1401.nupkg 29ms
Installing cef.redist.x64 3.2623.1401.
Adding package 'cef.redist.x64.3.2623.1401' to folder 'F:\C# Development\Winform projects\embebbedChromium\packages'
Added package 'cef.redist.x64.3.2623.1401' to folder 'F:\C# Development\Winform projects\embebbedChromium\packages'
Added package 'cef.redist.x64.3.2623.1401' to 'packages.config'
Successfully installed 'cef.redist.x64 3.2623.1401' to embebbedChromium
  GET https://api.nuget.org/packages/cef.redist.x86.3.2623.1401.nupkg
  OK https://api.nuget.org/packages/cef.redist.x86.3.2623.1401.nupkg 31ms
Installing cef.redist.x86 3.2623.1401.

每个人都喜欢成功的消息, 对吗?我做 !

继续操作之前的重要提示:通常, 对于最新版本的CefSharp, 建议在安装Nuget程序包后完全关闭Visual Studio, 然后重新打开(因为这样可以确保你的引用显示出来并具有完整的智能感知能力), 否则最终错误:

找不到类型或名称空间名称” Cefsharp”(你是否缺少using指令或程序集引用?)

找不到CefSharp名称空间

2)更改平台配置(x86, x64或AnyCPU)

成功安装后, 根据你使用的CefSharp的版本, 你需要配置一些东西以使其运行:

A. CefSharp 51版及更高版本

在CefSharp 51中, 你可以使用AnyCPU使用CefSharp, 但是它不能单独使用, 因为你需要在2个特定文件中进行一些更改。首先, 在项目中启用”首选32位”选项, 右键单击解决方案资源管理器中的”属性”项目(或在工具栏中的”项目”>”项目属性”中), 然后转到”构建”选项卡。在常规属性中, 选中”首选32位”选项:

首选32位Cefsharp

然后, 搜索your-project-name.csproj文件, 可以在<你的项目名称> / <你的项目名称> /你的项目名称.csproj中找到文件, 并在第一个<文件的PropertyGroup>:

<CefSharpAnyCpuSupport>true</CefSharpAnyCpuSupport>

你的* .csproj文件应如下所示:

CefSharp anyCPU支持

最后, 修改App.config文件, 该文件在Visual Studio中的项目的解决方案资源管理器中可见, 并在配置标记中添加以下标记:

<runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
        <probing privatePath="x86"/>
    </assemblyBinding>
</runtime>

然后, 你的配置文件将如下所示:

CefSharp AnyCPU app.config文件

如果你需要更多帮助或无法修改这些文件, 请在此处查看有关Github中AnyCPU的问题以获取更多帮助。

B. CefSharp 49版及更早版本(x86或x64)

对于CefSharp 49或更旧的版本, 你需要提供项目的体系结构, 否则CefSharp将无法正常工作。继续使用配置管理器更改项目的配置。

CefSharp不构建任何CPU

正如boromir所说, 你的项目的目标平台不能是任何CPU, 它必须是x86或x64, 否则你将在控制台中收到以下警告, 并且你的应用程序将无法编译。

CefSharp.Common does not work correctly on AnyCPU platform. You need to specify platform (x86 / x64).

继续先在配置管理器中进行更改。右键单击Visual Studio右上方区域的解决方案资源管理器(在解决方案中为Direct), 然后选择配置管理器:

CefSharp配置管理器

并选择与项目中的需求相匹配的平台:

正确的平台cefsharp

请注意, 如果不存在x86或x64, 则需要创建它们, 请选择<New …>选项, 将其添加然后选择。

在你的项目中对CefSharp进行基本配置之后, 该项目将成功构建, 因为我们拥有使用铬所需的一切。现在, 我们只需要添加到表单中并与代码一起使用即可。

3.1。使用CEF(作为浏览器)

现在我们的应用程序已经支持CefSharp, 我们只需要在代码中使用它即可。使用以下命令将CefSharp导入到你的代码中:

using CefSharp;
using CefSharp.WinForms;

现在添加以下方法, 并在你的类中创建一个类可访问变量作为浏览器(以在其他方法中使用):

public ChromiumWebBrowser chromeBrowser;

public void InitializeChromium()
{
   CefSettings settings = new CefSettings();
   // Initialize cef with the provided settings
   Cef.Initialize(settings);
   // Create a browser component
   chromeBrowser = new ChromiumWebBrowser("http://ourcodeworld.com");
   // Add it to the form and fill it to the form window.
   this.Controls.Add(chromeBrowser);
   chromeBrowser.Dock = DockStyle.Fill;
}

并在你类的InitializeComponent()函数之后执行它(通常在构造函数中):

public Form1()
{
     InitializeComponent();
     // Start the browser after initialize global component
     InitializeChromium();
}

不要忘记在表单的FormClosing事件中关闭cef组件:

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
     Cef.Shutdown();
}

现在你的类应如下所示(请注意, 该项目的名称为embebbedChromium):

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using CefSharp;
using CefSharp.WinForms;

namespace embebbedChromium
{
    public partial class Form1 : Form
    {
        public ChromiumWebBrowser chromeBrowser;
 
        public Form1()
        {
            InitializeComponent();
            // Start the browser after initialize global component
            InitializeChromium();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            
        }

        public void InitializeChromium()
        {
            CefSettings settings = new CefSettings();
            // Initialize cef with the provided settings
            Cef.Initialize(settings);
            // Create a browser component
            chromeBrowser = new ChromiumWebBrowser("http://ourcodeworld.com");
            // Add it to the form and fill it to the form window.
            this.Controls.Add(chromeBrowser);
            chromeBrowser.Dock = DockStyle.Fill;
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            Cef.Shutdown();
        }        
    }
}

现在启动你的应用程序(F5)或在工具栏中单击”开始”, 你将看到如何在C#Winforms应用程序中加载”我们的代码世界”。

我们在CefSharp浏览器中的代码世界

恭喜你!你刚刚以最基本的表达方式在应用程序中实现了CefSharp。我们建议你继续阅读框架文档, 并了解如何创建更出色的东西。

3.2。使用CEF(作为用户界面)

在上一点中, 你已经将CefSharp实现为浏览器组件。但是, 你还可以做更多的事情, 现在我们将使用本地文件实现纯HTML, Javascript和CSS(引导)UI并使用它来处理System事物。

我们需要在我们的Visual Studio项目中包含HTML资产。你可以直接从Visual Studio或Windows资源管理器中创建它们, 但通过Visual Studio则更容易, 因为该文件夹会自动添加到项目资源中。

在这种情况下, 我们将使用一个简单的Bootstrap接口(包括Bootstrap和jQuery), 该接口由以下目录组成:

资料夹路径

添加Visual Studio项目后(右键单击解决方案资源管理器, 然后在该项目上, 添加文件夹并将你的资源粘贴到此处), 该项目应如下所示:

Visual Studio资源浏览器

重要提示:现在, 你需要选择每个文件夹中的所有文件, 并执行以下操作:

  • 选择文件夹内的所有html, js, css资源。
  • 在底部, 将”复制到输出目录”值设置为”始终复制”。
始终复制

现在我们需要设置CefSharp指向我们的index.html文件而不是一个webUrl。现在我们的资源位于项目中, 你可以使用以下代码获取资源的路径:

请注意, 你需要始终提供文件的完整本地路径。由于普通项目需要能够在任何地方工作, 因此路径相对于我们项目的可执行文件。

// Now instead use http://ourcodeworld.com as URL we'll use the "page" variable to load our local resource
String page = string.Format(@"{0}\html-resources\html\index.html", Application.StartupPath);

但是, 这还行不通, 如果你现在尝试执行应用, 则会出现白屏。我们首先需要:

  1. 将要在Javascript中使用的C#类公开为一个对象。
  2. 允许使用本地文件(file://)。

我们将在Javascript中公开一个c#类, 以便使用Javascript操作本机函数。我们需要创建一个新类, 该类在构造函数中需要2个项目(ChromiumBrowserInstance和The Main Form)。此类将具有2个功能, 一个用于启动Chrome开发工具, 另一个用于启动Windows的命令提示符(cmd.exe)。

该类应如下所示:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using CefSharp;
using CefSharp.WinForms;
using System.Diagnostics;

namespace embebbedChromium
{
    class CefCustomObject
    {
        // Declare a local instance of chromium and the main form in order to execute things from here in the main thread
        private static ChromiumWebBrowser _instanceBrowser = null;
        // The form class needs to be changed according to yours
        private static Form1 _instanceMainForm = null;


        public CefCustomObject(ChromiumWebBrowser originalBrowser, Form1 mainForm)
        {
            _instanceBrowser = originalBrowser;
            _instanceMainForm = mainForm;
        }

        public void showDevTools()
        {
            _instanceBrowser.ShowDevTools();
        }

        public void opencmd()
        {
            ProcessStartInfo start = new ProcessStartInfo("cmd.exe", "/c pause");
            Process.Start(start);
        }
    }
}

此类将在Javascript中公开。稍后你将看到, 它是非常基本的, 显示了chrome浏览器的dev工具, 并启动了cmd.exe进程。

现在, 我们的InitializeChromium函数应如下所示:

public void InitializeChromium()
{
    CefSettings settings = new CefSettings();

    // Note that if you get an error or a white screen, you may be doing something wrong !
    // Try to load a local file that you're sure that exists and give the complete path instead to test
    // for example, replace page with a direct path instead :
    // String page = @"C:\Users\SDkCarlos\Desktop\afolder\index.html";

    String page = string.Format(@"{0}\html-resources\html\index.html", Application.StartupPath);
    //String page = @"C:\Users\SDkCarlos\Desktop\artyom-HOMEPAGE\index.html";

    if (!File.Exists(page))
    {
        MessageBox.Show("Error The html file doesn't exists : "+page);
    }
    
    // Initialize cef with the provided settings
    Cef.Initialize(settings);
    // Create a browser component
    chromeBrowser = new ChromiumWebBrowser(page);
       
    // Add it to the form and fill it to the form window.
    this.Controls.Add(chromeBrowser);
    chromeBrowser.Dock = DockStyle.Fill;
    
    // Allow the use of local resources in the browser
    BrowserSettings browserSettings = new BrowserSettings();
    browserSettings.FileAccessFromFileUrls = CefState.Enabled;
    browserSettings.UniversalAccessFromFileUrls = CefState.Enabled;
    chromeBrowser.BrowserSettings = browserSettings;
}

我们使用File.Exists方法来查看Providen路径是否存在, 否则在前面的步骤中你做错了什么。

现在我们只需要执行它, 并在InitializeComponent函数中公开该类:

public Form1()
{
    InitializeComponent();
    // Start the browser after initialize global component
    InitializeChromium();
    // Register an object in javascript named "cefCustomObject" with function of the CefCustomObject class :3
    chromeBrowser.RegisterJsObject("cefCustomObject", new CefCustomObject(chromeBrowser, this));
}
  • 如果你的项目与主磁盘位于不同的硬盘中, 请小心, 因为在开发中, 其他路径而不是(C://)很有可能失败。
  • 请注意, RegisterJsObject函数将全局类注册为以Providen名称作为第一个参数的类。在这种情况下, Javascript中的全局对象将是cefCustomObject。

而已 !现在你只需要证明该应用程序, 现在的主类应该与之前的所有代码看起来类似:

using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using CefSharp;
using CefSharp.WinForms;
using System.Runtime.InteropServices;

namespace embebbedChromium
{
    public partial class Form1 : Form
    {
        public ChromiumWebBrowser chromeBrowser;

        public Form1()
        {
            InitializeComponent();
            // Start the browser after initialize global component
            InitializeChromium();
            // Register an object in javascript named "cefCustomObject" with function of the CefCustomObject class :3
            chromeBrowser.RegisterJsObject("cefCustomObject", new CefCustomObject(chromeBrowser, this));
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            chromeBrowser.ShowDevTools();
        }

        public void InitializeChromium()
        {
            CefSettings settings = new CefSettings();

            // Note that if you get an error or a white screen, you may be doing something wrong !
            // Try to load a local file that you're sure that exists and give the complete path instead to test
            // for example, replace page with a direct path instead :
            // String page = @"C:\Users\SDkCarlos\Desktop\afolder\index.html";

            String page = string.Format(@"{0}\html-resources\html\index.html", Application.StartupPath);
            //String page = @"C:\Users\SDkCarlos\Desktop\artyom-HOMEPAGE\index.html";

            if (!File.Exists(page))
            {
                MessageBox.Show("Error The html file doesn't exists : "+page);
            }
            
            // Initialize cef with the provided settings
            Cef.Initialize(settings);
            // Create a browser component
            chromeBrowser = new ChromiumWebBrowser(page);
               
            // Add it to the form and fill it to the form window.
            this.Controls.Add(chromeBrowser);
            chromeBrowser.Dock = DockStyle.Fill;
            
            // Allow the use of local resources in the browser
            BrowserSettings browserSettings = new BrowserSettings();
            browserSettings.FileAccessFromFileUrls = CefState.Enabled;
            browserSettings.UniversalAccessFromFileUrls = CefState.Enabled;
            chromeBrowser.BrowserSettings = browserSettings;
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            Cef.Shutdown();
        }
    }
}

如前所述, 要处理Javascript部分, RegisterJsObject函数将创建一个名称为Providen作为第一个参数的对象。在index.html文件中, 我们将创建以下按钮, 这些按钮使用javascript执行本机功能:

<button class="btn btn-info" onclick="cefCustomObject.showDevTools();">Open Chrome Dev Tools</button>
<button class="btn btn-primary" onclick="cefCustomObject.opencmd();">Open cmd.exe</button>

记住要尊重” camelCase”, C#中的方法需要以lowerCase开头, 并遵守camelCase规则(没有下划线_), 如该类所示。

如你所见, 借助CefSharp, 一切都是双向的, 你可以轻松地从c#处理javascript或从javascript处理c#。

现在启动你的应用程序, 并在Windows中将HTML控件用作图形用户界面!

Chrome最终HTML UI

如果你在javascript中看到已注册的类, 你将看到具有所有已注册方法和功能的对象作为本机代码(等于, 自动添加getHashCode和toString)。

向C#注册的Javascript对象

玩得开心

赞(0)
未经允许不得转载:srcmini » 如何在Winforms应用程序中使用CefSharp(Chrome嵌入式框架c#)

评论 抢沙发

评论前必须登录!