关于CefSharp的坎坷之路

您所在的位置:网站首页 win7怎么打开摄像头拍照功 关于CefSharp的坎坷之路

关于CefSharp的坎坷之路

2024-05-21 09:13| 来源: 网络整理| 查看: 265

 

项目背景:

公司的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时会有对每个标签的描述信息,根据描述信息可以得知true其实是设置适应高高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 resolved 6 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 -- 6 10 Windows Vista -- 6 11 Windows Server 2003 R2 -- 5.2 12 Windows Server 2003 -- 5.2 13 Windows XP 64-Bit Edition -- 5.2 14 Windows XP -- 5.1 15 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: true 11 }, 12 // successCallback 13 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 // errorCallback 22 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");

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

 

结后语:

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

    

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3