让 CefSharp.WinForms 应用程序同时支持32位(x86)和64位(x64)的解决方案

当我们为基于 .NET Framework 的 WinForm 程序增加 CefSharp.WinForms 依赖后,可能会遇到以下报错信息:

CefSharp.Common is unable to proceeed as your current Platform is ‘AnyCPU’. To target AnyCPU please read https://github.com/cefsharp/CefSharp/issues/1714. Alternatively change your Platform to x86 or x64 and the relevant files will be copied automatically. For details on changing your projects Platform see https://docs.microsoft.com/en-gb/visualstudio/ide/how-to-configure-projects-to-target-platforms?view=vs-2017 CefSharpDemo

CefSharp.Common.targets

我们可以通过“配置管理器”为项目设置具体的 x86 或 x64 目标平台来消除该报错,同时我们也可以通过一些设置让我们的程序同时支持 x86 和 x64 目标平台。本篇将简述如何为依赖来 CefSharp.WinForms 的程序启用 AnyCPU 支持。英文版的操作步骤可参见:Feature Request – Add AnyCPU Support 。

为依赖 CefSharp 的程序增加 AnyCPU 支持

笔者新建了一个名为 CefSharpDemo 的 WinForm 项目,并通过 NuGet 引入 CefSharp.WinForms 组件:

首先,在项目上点击右键,选择“卸载项目”,在项目卸载成功后,再次点击右键,选择“编辑项目文件”。之后会看到以下类似的窗体:

在第一个 PropertyGroup 标签里增加 <CefSharpAnyCpuSupport>true</CefSharpAnyCpuSupport> 代码段:

修改完成之后,再次在项目文件上右击,选择“重新加载项目”。此番操作之后,项目的生成就不会报错了,可以发现在 bin 目录中多出了名为 x86 和 x64 的两个文件夹,分别对应 32 位和 64 位的应用程序。接下来我们需要在程序中根据运行环境,动态选择要加载的文件。

CefSharp 依赖文件的动态加载

我们可以通过 AppDomain.CurrentDomain.AssemblyResolve 事件将应用程序所需的组件注册进来。以下代码实现了该功能,并且根据是否 64 位进程选择具体加载哪个目录中的程序集:

using CefSharp;using CefSharp.WinForms;using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Reflection;using System.Runtime.CompilerServices;using System.Threading.Tasks;using System.Windows.Forms;namespace CefSharpDemo{static class Program{/// <summary>/// 应用程序的主入口点。/// </summary>[STAThread]static void Main(){Application.EnableVisualStyles();Application.SetCompatibleTextRenderingDefault(false);AppDomain.CurrentDomain.AssemblyResolve += Resolver;LoadApp();}[MethodImpl(MethodImplOptions.NoInlining)]private static void LoadApp(){var settings = new CefSettings();// Set BrowserSubProcessPath based on app bitness at runtimesettings.BrowserSubprocessPath = Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase,Environment.Is64BitProcess ? "x64" : "x86","CefSharp.BrowserSubprocess.exe");// Make sure you set performDependencyCheck falseCef.Initialize(settings, performDependencyCheck: false, browserProcessHandler: null);var frmMain = new FrmMain();Application.Run(frmMain);}// Will attempt to load missing assembly from either x86 or x64 subdirprivate static Assembly Resolver(object sender, ResolveEventArgs args){if (args.Name.StartsWith("CefSharp")){string assemblyName = args.Name.Split(new[] { ',' }, 2)[0] + ".dll";string archSpecificPath = Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase,Environment.Is64BitProcess ? "x64" : "x86",assemblyName);return File.Exists(archSpecificPath)? Assembly.LoadFile(archSpecificPath): null;}return null;}}}

至此,我们便实现了对 CefSharp 的 AnyCPU 支持。

CefSharp 应用支持 AnyCPU 的优缺点与解决方案

众所周知,相对于 32 位应用程序,64 位的应用拥有更快运行的运行速度,以及支持更多的内存。相对于分别对 x86 和 x64 分别发包的方式,AnyCPU 发包减少了运维成本,同时降低了客户下载程序包之后不能运行的风险。

但是 AnyCPU 的弊端也是很明显的:64 位的 libcef.dll 文件达到了 110兆,即便是本文所示的简单示例,全部文件的大小也达到了三百多兆:

要解决这个问题,我们可以在程序运行时动态去下载对应的依赖文件,该下载操作只要确保在调用 CefSharp 之前即可。

源代码

本文源代码:https://gitee.com/coderbusy/demo/tree/master/WinForm/CefSharpDemo

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/306601.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

算法设计与分析——贪心算法——活动安排问题

问题描述&#xff1a;设有n个活动的集合E{1,2,…,n}&#xff0c;其中每个活动都要求使用同一资源&#xff0c;如演讲会场等&#xff0c;而在同一时间内只有一个活动能使用这一资源。 每个活动i都有一个要求使用该资源的起始时间si和一个结束时间fi,且si<fi 。 如果选择了活动…

c语言——刷新控制台界面与返回上一级

#include<iostream> #include<stdlib.h> using namespace std;int main() {while(1){system("cls");//刷新控制台程序界面 cout<<"请输入1&#xff1a;进入下一级程序A:"<<endl;cout<<"请输入2&#xff1a;进入下一级程…

C# :异步编程的注意点

在上一篇《C#&#xff1a;异步编程中的 async 和 await》 中简单介绍了在 C# 中的异步编程以及 async 和 await 编程模型&#xff0c;本文介绍下异步编程的注意事项&#xff0c;主要有以下几个方面。同步中调用异步在同步代码中调用异步代码&#xff0c;容易导致死锁&#xff0…

makefile 打印变量_[Makefile] 缩进与空格--记录踩过的坑

今天折腾了好久&#xff0c;就为了debug两个makefile的bug。虽然最后找到原因了&#xff0c;但是&#xff0c;怎么说呢&#xff0c;用现在流行的话来说&#xff0c;实在是意难平啊&#xff01;必须写一篇记录一下&#xff01;第一个问题&#xff0c;是个语法高亮问题。今天观察…

算法设计与分析——贪心算法——背包问题

0-1背包问题&#xff1a; 前提&#xff1a;给定n种物品和一个背包。物品i的重量是Wi&#xff0c;其价值为Vi&#xff0c;背包的容量为C。 问题&#xff1a;应如何选择装入背包的物品&#xff0c;使得装入背包中物品的总价值最大? 背包问题&#xff1a; 与0-1背包问题类似&…

企业级精致 Blazor 套件 BootstrapBlazor 介绍

BootstrapBlazor1、前言 Blazor 作为一种 Web 开发的新技术已经发展有一段时间了&#xff0c;有些人标称 无 JS 无 TS&#xff0c;我觉得有点误导新人的意味&#xff0c;也有人文章大肆宣传 Blazor 是 JavaScript 的终结者&#xff0c;是为了替代 JavaScript 而生的&#xff0c…

算法设计与分析——贪心算法——最优装载问题

有一批集装箱要装上一艘载重量为c的轮船。其中集装箱i的重量为Wi。最优装载问题要求确定在装载体积不受限制的情况下&#xff0c;将尽可能多的集装箱装上轮船。 #include<iostream> #include<algorithm> #include<cstring> using namespace std;typedef str…

AgileConfig-轻量级配置中心 1.1.0 发布,支持应用间配置继承

AgileConfig轻量级配置中心自第一个版本发布不知不觉已经半年了。在并未进行什么推广的情况下收到了250个star&#xff0c;对我有很大的鼓舞&#xff0c;并且也有不少同学试用&#xff0c;并且给出了宝贵的意见&#xff0c;非常感谢他们。其中有一些意见非常好&#xff0c;但是…

如何在 C# 中使用 Dapper ORM

译文链接&#xff1a;https://www.infoworld.com/article/3025784/how-to-use-the-dapper-orm-in-c.html?nsdrtrue对象关系映射&#xff08;ORM&#xff09;这个概念已经存在很长时间了&#xff0c;ORM的作用就是用来解决 编程领域的 object model 和关系数据库中的 data mode…

GraphQL:简单开开始一个查询

GraphQL 既是一种用于 API 的查询语言也是一个满足你数据查询的运行时。GraphQL 对你的 API 中的数据提供了一套易于理解的完整描述&#xff0c;使得客户端能够准确地获得它需要的数据&#xff0c;而且没有任何冗余&#xff0c;也让 API 更容易地随着时间推移而演进&#xff0c…

算法设计与分析——回溯法——批处理作业调度

问题描述&#xff1a;给定n个作业的集合{J1,J2,…,Jn}。每个作业必须先由机器1处理&#xff0c;然后由机器2处理。作业Ji需要机器j的处理时间为tji。对于一个确定的作业调度&#xff0c;设Fji是作业i在机器j上完成处理的时间。所有作业在机器2上完成处理的时间和称为该作业调度…

探索.NET平台中的SIMD内在函数Vector

概述Vector&#xff08;向量&#xff09;是一种序列式容器&#xff0c;事实上和数组差不多&#xff0c;但它比数组更优越。一般来说数组不能动态拓展&#xff0c;因此在程序运行的时候不是浪费内存&#xff0c;就是造成越界。而Vector刚好弥补了这个缺陷&#xff0c;它的特征是…

算法设计与分析——回溯法——装载问题

0027算法笔记——【回溯法】回溯法与装载问题 自己写的代码&#xff1a; #include <iostream> using namespace std; template <class Type> class Loading {//friend Type MaxLoading(Type[],Type,int,int []);//private:public:void Backtrack(int i);int n, …

深入解析 C# 的 String.Create 方法

作者&#xff1a;Casey McQuillan译者&#xff1a;精致码农原文&#xff1a;http://dwz.win/YVW说明&#xff1a;原文比较长&#xff0c;翻译时精简了很多内容&#xff0c;对于不重要的细枝末节只用了一句话概括&#xff0c;但不并影响阅读。你还记得上一次一个无足轻重的细节点…

算法设计与分析——回溯法——n皇后问题

一、什么是N皇后问题&#xff1f; 在nn格的棋盘上放置彼此不受攻击的n个皇后。按照国际象棋的规则&#xff0c;皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。n后问题等价于再nn的棋盘上放置n个皇后&#xff0c;任何2个皇后不妨在同一行或同一列或同一斜线上。 问题…

全局程序集缓存gac中安装程序集_我就不信2W字把源码拆的这么碎,你还不明白mybatis缓存...

前言不知道大家看到这张图感觉怎么样&#xff0c;不是难&#xff0c;一共也没有几个组件&#xff0c;但是真的让我想当头疼&#xff0c;因为在面试的时候&#xff0c;就这张图&#xff0c;对&#xff0c;你没看错&#xff0c;就这几个组件&#xff0c;那是让我相当难受啊MyBati…

GraphQL:和EntityFramework更配哦

GraphQL 既是一种用于 API 的查询语言也是一个满足你数据查询的运行时。GraphQL 对你的 API 中的数据提供了一套易于理解的完整描述&#xff0c;使得客户端能够准确地获得它需要的数据&#xff0c;而且没有任何冗余&#xff0c;也让 API 更容易地随着时间推移而演进&#xff0c…

算法设计与分析——回溯法——符号三角形问题

#include<iostream> using namespace std;class Triangle{public:void Backtrack(int t);int n;//第一行的符号个数 int half;//n*(n1)/4 int count;//当前—的个数 int **p;//符号三角形矩阵 long sum; //已找到的符号三角形数 };void Triangle::Backtrack(int t) {if(…

mysql 默认事务隔离级别_MySQL 事务隔离级别详解

个人公众号『码农札记』&#xff0c;欢迎关注&#xff0c;查看更多精彩文章。 简介&#xff1a; MySQL的事务隔离级别一共有四个&#xff0c;分别是读未提交、读已提交、可重复读以及可串行化。四个特性ACID原子性 &#xff08;Atomicity&#xff09;事务开始后所有操作&#x…

如何在 Asp.Net Core 中对请求进行限流

译文链接&#xff1a;https://www.infoworld.com/article/3442946/how-to-implement-rate-limiting-in-aspnet-core.html在应用程序开发时&#xff0c;或许你有这样的想法&#xff0c;控制用户的请求频率来防止一些用户的恶意攻击&#xff0c;具体的说就是&#xff1a;为了预防…