博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
关于CefSharp的坎坷之路
阅读量:5213 次
发布时间:2019-06-14

本文共 8459 字,大约阅读时间需要 28 分钟。

原文:

 

项目背景:

公司的XX产品需要升级和以后支持多平台的使用。因为之前项目是由WPF实现的。目前以后想作为Html5来展示页面。

因为涉及到整体更改遇到的问题较多以及其他原因,所以只是内部内容区域先替换为Html5页面,所以需要嵌入Browser控件。

Browser控件的选型:

1.Winform中的WebBrowser

2.WPF中的WebBrowser

3.WebKit.Net

4.CefSharp

5.awesominum

6.OpenWebKitSharp

7. geckofx

经过初步查阅,WebKit.Net、OpenWebKitSharp 和geckofx 都是基于Winform的。CefSharp 在GitHub有源码,并且具备Winform和WPF的版本。awesominum可以允许把网页嵌入到 3D 画面或游戏中,支持unity3D。

经过尝试.Net中的Winform版本的WebBrowser,背景无法直接设置透明, 需要通过Windows Api进行处理(仅查阅,未实际进行处理和验证)。

首先把Winform的WebBrowser放到项目中进行了实验和处理,发现两个致命问题:一个是背景不透明,因为整个背景具有渐变和过渡效果。第二个是,页面切换具有滑动过渡效果。

Winform版的WebBrowser会悬浮最上层,不会渐变隐藏消失。  基于以上两点,针对Winform和基于Winform的其他暂时不在考虑。

(调研其他基于Winform的第三方控件没有具体查看是否内部已经处理这些问题,喜欢深入研究的同学或使用过的同学也可以告诉我啊)

目前 调研CefSharp和Awesominum。

CefSharp的源码Demo进行测试,目前是符合需求。Awesominum初步查看也符合需求。

特定需求:在某个Html5页面中 需要调用摄像头进行录像拍摄。

现象:在CefSharp的初步显示具备摄像头打开的页面时,无法打开摄像头。开始查找问题,最后发现 要给CefSharp的CommandLineArgs添加一些命令才可以显示处理,并且要启动WebServer服务。(后面会详细讲解此问题)

而在Awesominum中未找到可以添加命令行参数的方法,所以姑且放弃。最好还是先选用CefSharp。

目前,引用CefSharp,我是通过Nuget进行获取安装的。

关于Nuget的使用,大家可以自行搜索使用。Nuget还可以自己搭建公司专属的插件服务器和客户端调用。

其中需要注意的是:

1.使用正确的Package source资源地址进行搜索下载。

如下图,在搜搜CefSharp的时候,要使用nuget.org地址或All下载资源,这样才能搜索到CefSharp,Microsoft Visual Studio Offline Packages 则是针对微软的一些插件和应用包。

2.插件的安装和卸载都要要用Nuget进行处理

在使用过程中,有时候会遇到解决方案打开,然后操作生成项目时,提示正在恢复还原Nuget包,然后,然后,就一直然后了... 那叫个等的花都谢了。强制关闭,下次还是会有滴。还是放弃抵抗吧。

如果Nuget的包恢复和还原出来错活着不需要了,还是通过Nuget进行卸载,以免有残留。真是不使用不知道,一使用全乱套,啊哈哈~~~~

纯属个人体会,个中滋味,各自体会。

----------------以下为使用CefSharp过程中,个人遇到的一些问题和注意事项------------------------

一:引用CefSharp的编译需要指定目标平台X86或X64

    在我们解决方案中,一般默认都是AnyCup的,所以在生成时会提示错误。

因为CefSharp的使用需要明确目标平台的。所以生成时,要指定是x86还是x64,因为我们项目需要 要改为X86.  有的会问,我已经修改目标平台为x86了,如下图 位置:1、2处。而编译还是生成不成功呢?这是为什么呢?为什么呢?

请不要在项目的属性上进行设置。要在整个解决方案的配置上进行设置 引用CefSharp的项目的Platform 平台。仔细看你会发现 解决方案的的项目的平台如下图 位置3处和 项目属性中是不一致的呢。所以切记。

二:CefSharp中的生成目录的问题

在我们项目中,CefSharp的项目是作为插件的方式嵌入主框架中的,所以生成目录到了根目录下的Plugins目录下。运行后,你会发现一直提示无法找到CefSharp.core.dll等相关的dll文件。  哈哈,找不到,找不到就对了。

CefSharp是到根目录下(默认是指Bin)的环境中寻找dll的,所以无法进行找到。暂时也未从源码案例中找到进行设置目录的方式(若其他忍知晓可以告知我哦)。

不过这样也不要紧,不就是在程序的运行环境中找不到吗?我们自己添加上不就行了。代码如下:

var pluginsPath = Path.Combine(Environment.CurrentDirectory, "Plugins");  var path = Environment.GetEnvironmentVariable("PATH") + ";" + pluginsPath;  Environment.SetEnvironmentVariable("PATH", path, EnvironmentVariableTarget.Process);

  在程序运行启动时,把对应的环境变量路径添加上Plugins的路径。运行起来,你会发现可以了。

三:关于CefSharp生成时产生的各种文件是否项目都必须用到的问题

    比如,生成的文件中有扩展名为.pak的文件,pak文件是一种特殊的文件压缩格式。 比较常应用于游戏。 关于此类文件,在使用CefSharp也需要具备此类文件。 

网上搜索:将locales及其下所有都设置为输出,里面有个en-US.pak文件,如没有,则应用程序会启动显示错误退出。再将devtools_resources.pak 设置为输出,否则调用devtools时将报错不能打开。(常见问题官网解释)
通过在CefSharp的源码中搜索也确实使用到了pak文件,所以此类文件也不可缺少。

四:关于CefSharp显示页面一直闪烁的问题。

      具体查找过程就不详述,只能一把鼻涕一把泪的说 那也是一个煎熬的过程,不能说问题有多大,只能说很小的问题,没有找对方向。现在就把问题告诉大家。   

      经过和从GitHub下载的CefSharp3的源码进行对比,最终发现,我们未进行配置app.manifest文件的配置,大神们也许很多app.manifest文件的用途,而对于我这种不踩一两次坑,不长教训的,以前都会轻轻掠过这种东西。

      app.manifest的文件可以通过添加文件来自动生成。也可以从源码中拷贝过来。然后在项目的属性=》应用(Application)中进行Resources=》Manifest配置上。下面描述app.manifest的描述的功能。

     其中主要 代码片段入下:   

1  
2
3
6 7
8
9 10
11
12 13
14
15 16
17
18 19
20
21 22
23
24 25
29 30
31
32
true
33
34
app.manifest的主要代码片段
 

 自动添加app.manifest时会有对每个标签的描述信息,根据描述信息可以得知<dpiAware>true</dpiAware>其实是设置适应高高dpi对程序的影响。目前很多电脑都是高dpi的。

    应该是 不同操作系统下,渲染机制是有区别的,所以为了更好的适应高dpi和不同系统的影响,所以最好不同的系统可以按照自己专属的环境进行处理,而supportedOs标签的设置解决了这类问题。

五:关于Windows8.1系统运行程序 页面依旧闪烁的原因。

在配置好app.manifest之后,以为可以源码的解决了页面闪烁的问题。而后,被告知Windows8.1的系统却依旧闪烁。这下又懵逼了~~懵逼~~了~~~!!!

后来又仔细阅读关于CefSharp中的代码和各种配置,在源码CefSharp3的命令行参数CefCommandLineArgs的配置中惊奇的发现了下面一段代码:

1  var osVersion = Environment.OSVersion;2             //Disable GPU for Windows 7   3             if (osVersion.Version.Major == 6 && osVersion.Version.Minor == 1)4             {5                 // Disable GPU in WPF and Offscreen examples until #1634 has been resolved6                 settings.CefCommandLineArgs.Add("disable-gpu", "1");7             }
CefSharp禁用GPU的命令行参数

其中,Major和Minor分别指代系统的主版本(大版本)、次版本(小版本)版本号。其中指定了Windows7系统会禁用 GPU。,突发奇想,是否windows8.1也是因为这个问题?然后开始验证。

所以,经查阅,各系统的对应版本如下:

系统的主版本、次版本

1 Windows 10 -- 10.0* 2 Windows Server 2016 Technical Preview -- 10.0* 3 Windows 8.1 -- 6.3* 4 Windows Server 2012 R2 -- 6.3* 5 Windows 8 -- 6.2 6 Windows Server 2012 --6.2 7 Windows 7 -- 6.1 8 Windows Server 2008 R2 -- 6.1 9 Windows Server 2008 -- 610 Windows Vista -- 611 Windows Server 2003 R2 -- 5.212 Windows Server 2003 -- 5.213 Windows XP 64-Bit Edition -- 5.214 Windows XP -- 5.115 Windows 2000 -- 5
系统的主版本、次版本

如上图得知,若判断是否为Windows8.1系统,判断osVersion.Version.Major == 6 && osVersion.Version.Minor == 3 即可,

但是不知源码中 为何要判断windows7的禁用GPU,在windows7下取消禁用GPU的测试,发现页面并未闪烁。

但是为了安全起见,并且身边没有window8和其他的系统,所以决定,应用CefSharp的时候,配置CefCommandLineArgs进行了只判断osVersion.Version.Major == 6的处理,即windows8.1、windows8、windows7等都禁用了GPU。

暂且不知,这以后是否会成为历史遗留问题~~~~~嘻嘻~~。

六:关于  调试状态运行程序不报错,但是页面却一直未显示的问题

              直接运行exe程序,提示找不到 CefSharp.BrowserSubprocess.exe和CefSharp.Core.dll等missing的问题。

     在操作cefsharp项目并拷贝文件到输出目录过程中,会未对CefSharp.BrowserSubprocess.exe进行处理,导致CefSharp对应的运行环境下未有CefSharp.BrowserSubprocess.exe文件。

    而CefSharp的浏览器是需要依赖此文件的,所以,才会出现页面显示不出画面的问题。CefSharp.BrowserSubprocess.exe文件是安装Nuget时自动下载下来的,但是在项目应用过程中,并不会拷贝生成到特定的输出目录下,

    所以,想把此文件进行保存下载,上次到源码管理中,生成的时候也自动复制到输出目录,以避免丢失此文件而报错的情况。

处理方式:

在项目中添加了Files文件,并把CefSharp.BrowserSubprocess.exe 放入其中,设置属性为Content和Copy Always 

设置项目生成成功后的脚本,拷贝到运行环境目录 即可。

七:关于使用CefSharp起用摄像头的问题

     为什么要针对这个问题拿出来说一说你呢?可能会有人问:调用摄像头不是js操作的问题吗?跟CefSharp有什么关系。          请往下看eb( ̄▽ ̄)d

     因项目要显示的网页中 有一个需要打开摄像头拍照的功能,js的代码如下:    

1  var mediaStream = null, track = null; 2     var video; 3     var n = 0; 4     navigator.getMedia = (navigator.getUserMedia || 5         navigator.webkitGetUserMedia || navigator.mozGetUserMedia || 6         navigator.msGetUserMedia); 7     if (navigator.getMedia) { 8         navigator.getMedia( 9             {10                 video: true11             },12             // successCallback13             function (stream) {14                 var s = window.URL.createObjectURL(stream);15                 video = document.getElementById('video');16                 video.src = window.URL.createObjectURL(stream);17                 mediaStream = stream;18                 track = stream.getTracks()[0];19                 $scope.photoBtnDiable = false; $scope.$apply();20             },21             // errorCallback22             function (err) {23                 $scope.errorPhoto();24                 console.log("The following error occured:" + err);25             });26     } else {27         $scope.errorPhoto();28     }29     //拍照30     $scope.snap = function () {31         var canvas1 = document.getElementById('canvas1');32         var canvas2 = document.getElementById('canvas2');33 34         var ctx1 = canvas1.getContext('2d');35         var ctx2 = canvas2.getContext('2d');36 37         ctx1.drawImage(video, 0, 0, canvas1.width, canvas1.height);38         n++;39         if (n % 2 == 0) {40             ctx2.drawImage(video, 0, 0, canvas2.width, canvas2.height);41         } else {42             ctx1.drawImage(video, 0, 0, canvas1.width, canvas1.height);43         }44         //$uibModalInstance.close(canvas.toDataURL("image/png"));45     };46     //关闭摄像头47     $scope.closeCamera = function () {48         if (mediaStream != null) {49             if (mediaStream.stop) {50                 mediaStream.stop();51             }52             $scope.videosrc = "";53         }54         if (track != null) {55             if (track.stop) {56                 track.stop();57             }58         }59     }
JS调用摄像头拍照代码

    测试运行后发现在CefSharp使用,不起作用。因为我们访问页面一开始是通过file:///url的方式进行本地访问的。有经验的朋友会发现,浏览器很多(比如调动摄像头)的操作只支持安全源访问,并且有的浏览器会提示是否允许启动摄像头。 

    为了能使用摄像头所以需要启动web 服务,以http或者localhost的方式进行访问。因为,通过HttpListener搭建了个Web 服务,然后测CefSharp3的页面依旧不可以调用摄像头,经过通过其他浏览器调用显示没有问题。

    这下又一头雾水,经过查阅资料,滚滚洪水中找到了那一颗螺丝钉,又位使用过CefSharp的一位 的说明中提到了 CefSharp要进行参数配置的如下:

    在CefCommandLineArgs添加了enable-media-stream参数,意思是启用媒体流

//主要是配置开启Media的命令参数,此配置可以允许摄像头打开摄像            settings.CefCommandLineArgs.Add("enable-media-stream", "1");

    忆往昔岁月,已然犹记此些。

 

结后语:

     第一次认真编写博客,排版等还有待完善。希望各位博友多鼓励,多指教。

     我近期设立了一个小目标:(比如 先赚他一个亿,哈哈) 多发博文和博友互动,整理思路,弥补不足,多学习开源,参与开源。忘自己以后会越来越牛~~~~~~~

 

posted on
2018-08-01 16:30 阅读(
...) 评论(
...)

转载于:https://www.cnblogs.com/lonelyxmas/p/9402034.html

你可能感兴趣的文章
php经典算法面试题
查看>>
防止SQL注入
查看>>
Laravel 安全:避免 SQL 注入
查看>>
跨站请求CSRF攻击
查看>>
jsonp原理详解
查看>>
详解PHP如何实现单点登录
查看>>
集群间如何实现session共享
查看>>
秒杀场景案例分析
查看>>
cron表达式详解
查看>>
php中fastcgi和php-fpm是什么东西
查看>>
linux ps 命令参数详解
查看>>
ubuntu切换到root用户
查看>>
Ubuntu 无法进行SSH连接,开启22端口
查看>>
ubuntu server 14.04和18.04挂载vmware共享文件夹
查看>>
ubuntu-18.04 设置开机启动脚本
查看>>
ubuntu下搭建LNMP开发环境
查看>>
ubuntu配置静态IP
查看>>
JMeter接口测试
查看>>
JMeter使用JSON Extractor插件实现将一个接口的JSON返回值作为下一个接口的入参
查看>>
Jmeter发送post请求报错Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported...
查看>>