为 CefSharp 应用内置 C++ 运行环境并启用 AnyCPU 支持

一个 CefSharp 应用程序要想正确运行,有两个必要条件:

  1. .NET Framework 4.5.2

  2. VC++ 2015

在部署 CefSharp 应用时经常会遇到因为没有 VC++ 2015 而无法运行的问题:

通过事件查看器,可以观察到一个类型为:System.IO.FileNotFoundException 的异常。

检测 VC++ 2015 运行环境是否安装。

我们可以使用以下 C# 代码来检测本机上是否已经部署了 VC++ 2015 运行环境:

public static bool IsVc2015Installed(){var dependenciesPath = @"SOFTWARE\Classes\Installer\Dependencies";var plat = Environment.Is64BitProcess ? "x64" : "x86";using (var dependencies = Registry.LocalMachine.OpenSubKey(dependenciesPath)){if (dependencies == null){return false;}foreach (var subKeyName in dependencies.GetSubKeyNames().Where(n =>!n.ToLower().Contains("dotnet") && !n.ToLower().Contains("microsoft"))){using (var subDir = Registry.LocalMachine.OpenSubKey(dependenciesPath + "\\" + subKeyName)){if (subDir == null){continue;}var value = subDir.GetValue("DisplayName")?.ToString() ?? null;if (string.IsNullOrEmpty(value)){continue;}if (Regex.IsMatch(value, $@"C\+\+ 2015.*\({plat}\)")) //here u can specify your version.{return true;}}}}return false;}

内置 VC++ 2015 运行时文件

VC++ 2015 运行环境是可以通过 XCopy 部署的。即:如果我们的程序需要 VC++ 2015 运行环境,仅需将 VC++ 2015 的全部文件复制到应用程序目录即可。事实上,有很多商业软件也是这么做的,比如:Navicat 。应用程序目录下一系列 “api-ms-win” 开头的 DLL 文件就是运行时文件。

当我们的 CefSharp 的目标平台仅为 x86 或 x64 ,内置 VC++ 2015 运行时仅需将对应的文件复制到输出目录即可。

如果要启用 AnyCPU 支持,我们仍需为主程序装载 VC++ 2015 运行时。

启用 AnyCPU 支持

以上一篇 让 CefSharp.WinForms 应用程序同时支持32位(x86)和64位(x64)的解决方案 的代码为模板,在 Program 文件中增加 _dllLoaded 变量来保存 VC++ 2015 环境是否已经具备。在 Program 类型的静态构造函数中调用 IsVc2015Installed 函数来确认是否已经安装了 VC++ 2015 环境,并将结果赋值给 _dllLoaded 变量。这代表着,如果本机已经安装过 VC++ 2015 运行环境,则程序内置的环境将不会被加载。

可以使用以下 Windows API 加载非托管类库:

[DllImport("kernel32.dll")]private static extern IntPtr LoadLibrary(string lpFileName);

声明静态的只读字符串数组变量 DllList 用于保存 VC++ 2015 的全部文件名:

private static readonly string[] DllList ={"api-ms-win-core-console-l1-1-0.dll", "api-ms-win-core-datetime-l1-1-0.dll","api-ms-win-core-debug-l1-1-0.dll", "api-ms-win-core-errorhandling-l1-1-0.dll","api-ms-win-core-file-l1-1-0.dll", "api-ms-win-core-file-l1-2-0.dll","api-ms-win-core-file-l2-1-0.dll", "api-ms-win-core-handle-l1-1-0.dll","api-ms-win-core-heap-l1-1-0.dll", "api-ms-win-core-interlocked-l1-1-0.dll","api-ms-win-core-libraryloader-l1-1-0.dll", "api-ms-win-core-localization-l1-2-0.dll","api-ms-win-core-memory-l1-1-0.dll", "api-ms-win-core-namedpipe-l1-1-0.dll","api-ms-win-core-processenvironment-l1-1-0.dll", "api-ms-win-core-processthreads-l1-1-0.dll","api-ms-win-core-processthreads-l1-1-1.dll", "api-ms-win-core-profile-l1-1-0.dll","api-ms-win-core-rtlsupport-l1-1-0.dll", "api-ms-win-core-string-l1-1-0.dll","api-ms-win-core-synch-l1-1-0.dll", "api-ms-win-core-synch-l1-2-0.dll","api-ms-win-core-sysinfo-l1-1-0.dll", "api-ms-win-core-timezone-l1-1-0.dll","api-ms-win-core-util-l1-1-0.dll", "api-ms-win-crt-conio-l1-1-0.dll","api-ms-win-crt-convert-l1-1-0.dll", "api-ms-win-crt-environment-l1-1-0.dll","api-ms-win-crt-filesystem-l1-1-0.dll", "api-ms-win-crt-heap-l1-1-0.dll","api-ms-win-crt-locale-l1-1-0.dll", "api-ms-win-crt-math-l1-1-0.dll","api-ms-win-crt-multibyte-l1-1-0.dll", "api-ms-win-crt-private-l1-1-0.dll","api-ms-win-crt-process-l1-1-0.dll", "api-ms-win-crt-runtime-l1-1-0.dll","api-ms-win-crt-stdio-l1-1-0.dll", "api-ms-win-crt-string-l1-1-0.dll","api-ms-win-crt-time-l1-1-0.dll", "api-ms-win-crt-utility-l1-1-0.dll","ucrtbase.dll"};

新增 CheckDll 方法,根据运行环境加载对应的 VC++ 2015 运行时:

private static void CheckDll() // 检查浏览器的DLL是否载入{if (_dllLoaded){return;}var dir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Environment.Is64BitProcess ? "x64" : "x86");foreach (var fname in DllList){try{var path = Path.Combine(dir, fname);if (File.Exists(path)){LoadLibrary(path);}}catch{}}_dllLoaded = true;}

注意:CheckDll 需要在 Resolver 方法中被调用。完成以上操作后,CefSharp程序就可以在未安装 VC++ 2015 环境的机器上成功运行了:

开源

本文所展示的全部代码和项目工程均在 Gitee 上开源。完整的项目文件和依赖文件可以在以下地址拿到:

https://gitee.com/coderbusy/demo/tree/master/WinForm/CefSharpEmbedCppRunTime

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

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

相关文章

java file rename 失败_java重命名文件造成文件不可读写

我想使用java代码对nginx日志文件进行拆分,但是我发现代码执行之后,拆分出来的日志文件没有读写权限,查看文件属性,显示的很诡异:点击高级按钮,显示你没有权限查看或者编辑这个对象的权限设置:反…

java opencsv_用opencsv文件读写CSV文件

首先明白csv文件长啥样儿:用excel打开就变成表格了,看不到细节推荐用其它简单粗暴一点儿的编辑器,比如Notepad,csv文件内容如下:csv文件默认用逗号分隔各列。有了基础的了解就进入主题,用Opencsv读写csv文件…

Beetlex之tcp/tls服务压测工具

在编写tcp服务的时候经常需要对服务的基础性能进行一个压力测试,虽然网上这些工具有很多,但具备使用方便和高强度的测试工具则不多。为了方便这方面的高强度压测所以在beetlex的基础扩展这样一个工具。安装可以访问https://github.com/beetlex-io/TCPBen…

GraphQL:DataLoader的神奇

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

【Azure Show】|第九期 “我的计算机入门之路” 嘉宾秦婷婷汪宇杰文轩

欢迎来到Azure Show!Azure Show欢迎来到Azure Show 第九期!继上期【搭上AI快车】为大家带来数位微软技术专家于各自IT技术领域的经验分享,有2400多人在线上通过b站看了这个特辑的直播,非常非常感恩!本期继续和广州图书馆合作&…

调试实战 | 通过转储文件分析程序无响应之使用 windbg + IDA 逆向篇

缘起 最近,接连在项目中遇到了两个界面无响应的问题。都只发生在客户特定机器上,不方便直接调试,只能抓取 dump 进行事后分析了。抓取 dump 远程连上可以重现问题的机器,使用 process explorer 初步观察卡死的进程,发现…

跟我一起学Redis之高可用从主从复制开始

前言现在遇到高并发场景时,缓存技术应该算是性能优化的第一步,缓解数据库压力的同时还能提高访问效率,而Redis应该是绝大多数应用场景的首选。但是尽快Redis性能再优秀,在当今高并发场景下,一台服务器负责读写&#xf…

【.Net core】EFCore——Code First生成数据库与表

Code First——领域设计模式中非常有用。使用 Code First 模式,专注于领域设计,创建领域类,然后生成数据库。1.创建数据模型类一般就是数据库里面有哪些表,就创建哪些模型, POCO 类就够了。public partial class SmsPu…

龙芯.NET正式发布 开源共享与开发者共成长

2020年12月19日,2020中国. NET开发者大会于苏州盛大开幕。本次大会以“开源、共享、创新”为主题,以线下城市苏州为中心,覆盖北京、上海、深圳、广州、长沙、成都、厦门、胶东等地区,是中国 .NET 开发者的大聚会,线上线…

划入 .NET 6版本目标,微软鼓励开发人员信任第三方库

喜欢就关注我们吧!鉴于许多 .NET 社区的开发人员都不愿意使用非微软官方打造的库,近日,微软 .NET Framework 团队的项目经理 Immo Landwerth 发布了一个名为”Growing the .NET ecosystem“的文档,以鼓励 .NET 开发人员加强对第三…

归并排序 java 迭代_经典排序算法之归并排序(示例代码)

归并排序(英语:Merge sort,或mergesort),是创建在归并操作上的一种有效的排序算法,效率为(大O符号)。1945年由约翰冯诺伊曼首次提出。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用,且各层分治递归可以…

新鲜高频笔面试题分享,Redis、MongoDB、ElasticSearch...

2020年可能是最短的一年,上班没几个月就发现要元旦了;2020年可能是最难的一年,各种降薪被离职风波;然而好消息是,2021年马上来了,跳槽季也要来了,一起开始备战吧,新年薪资up up&…

在 Windows 服务中托管 ASP.NET Core

概述众所周知,ASP.NET Core采用了和传统ASP.NET不同的托管和HTTP处理方式,即把服务器和托管环境完全解耦。ASP.NET Core内置了两个HTTP服务器实现,一个是基于libuv实现的Kestrel(支持跨平台),一个是基于Win…

目录 | 数据结构与剑指Offer系列推文合集

【目录合集】| 作者 / Edison ZhouC#刷数据结构剑指Offer不知不觉,C#刷剑指Offer的系列推文就结束了,今天就把它们整理成目录合集。此外,考虑到剑指Offer和数据结构的关联,建议没有数据结构基础的童鞋先看看数据结构,再…

Abp vNext异常处理的缺陷/改造方案

之前吐槽Abp的用户/租户管理模块!今天我又来了,这次我给Abp官方repo提了一个issue。目前Website使用Abp vNext开发,免不了要全局处理异常、提示服务器异常信息。1. Abp官方异常处理Abp项目默认会启动内置的异常处理,默认不将异常信…

开源项目葫芦藤:IdentityServer4的实现及其运用

前言本篇文章主要是讲解葫芦藤项目中对IdentityServer的实践使用,为了使您对本篇文章中所讲述的内容有深刻的认识,并且在阅读时避免感到乏味,文中的内容不会涉及太多的基础理论知识,而更多的是采用动手实践的方式进行讲解&#xf…

java io 读取多个对象_Java IO系列(五):读写对象ObjectOutputStream和ObjectInputStream详解...

有必要多看几遍的关于字符和字节,例如文本文件,XML这些都是用字符流来读取和写入。而如RAR,EXE文件,图片等非文本,则用字节流来读取和写入。读写对象,传输对象在Java中很常使用,在javaBean中就经…

Beetlex之websocket/tls服务压测工具

为了方便压力测试ws服务,Beetlex同样提供相关工具来对ws/wss服务的性能进行测试测试。安装可以访问https://github.com/beetlex-io/TCPBenchmarks 下载最新版本工作,工具可以运行在linux和windows系统,安装完成后通过浏览器访问相关服务进行操…

大学班里80%都去培训班,为什么我没去

背景大四刚开始,各大培训机构就开始到各大高校开始宣传,我们学校也不例外;当时信息与计算科学这专业在我们学校并不景气,有好几次听说:如果我们那届的就职率还不行的话,那很大可能将此专业拿掉;…

如何在 C# 中使用 Buffer

缓冲区 是内存中的一组字节序列,缓冲 是用来处理落在内存中的数据,.NET 缓冲 指的是处理 非托管内存 中的数据,用 byte[] 来表示。当你想把数据写入到内存或者你想处理非托管内存中的数据,可以使用 .NET 提供的 System.Buffer类&a…