关于CefSharp的坎坷之路
项目背景:
公司的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的描述的功能。
其中主要 代码片段入下:
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- A list of the Windows versions that this application has been tested on and is
is designed to work with. Uncomment the appropriate elements and Windows will
automatically selected the most compatible environment. --> <!-- Windows Vista -->
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" /> <!-- Windows -->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" /> <!-- Windows -->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" /> <!-- Windows 8.1 -->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" /> <!-- Windows -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" /> </application>
</compatibility> <!-- Indicates that the application is DPI-aware and will not be automatically scaled by Windows at higher
DPIs. Windows Presentation Foundation (WPF) applications are automatically DPI-aware and do not need
to opt in. Windows Forms applications targeting .NET Framework 4.6 that opt into this setting, should
also set the 'EnableWindowsFormsHighDpiAutoResizing' setting to 'true' in their app.config. --> <application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
</windowsSettings>
</application>
app.manifest的主要代码片段
自动添加app.manifest时会有对每个标签的描述信息,根据描述信息可以得知<dpiAware>true</dpiAware>其实是设置适应高高dpi对程序的影响。目前很多电脑都是高dpi的。
应该是 不同操作系统下,渲染机制是有区别的,所以为了更好的适应高dpi和不同系统的影响,所以最好不同的系统可以按照自己专属的环境进行处理,而supportedOs标签的设置解决了这类问题。
五:关于Windows8.1系统运行程序 页面依旧闪烁的原因。
在配置好app.manifest之后,以为可以源码的解决了页面闪烁的问题。而后,被告知Windows8.1的系统却依旧闪烁。这下又懵逼了~~懵逼~~了~~~!!!
后来又仔细阅读关于CefSharp中的代码和各种配置,在源码CefSharp3的命令行参数CefCommandLineArgs的配置中惊奇的发现了下面一段代码:
var osVersion = Environment.OSVersion;
//Disable GPU for Windows 7
if (osVersion.Version.Major == && osVersion.Version.Minor == )
{
// Disable GPU in WPF and Offscreen examples until #1634 has been resolved
settings.CefCommandLineArgs.Add("disable-gpu", "");
}
CefSharp禁用GPU的命令行参数
其中,Major和Minor分别指代系统的主版本(大版本)、次版本(小版本)版本号。其中指定了Windows7系统会禁用 GPU。,突发奇想,是否windows8.1也是因为这个问题?然后开始验证。
所以,经查阅,各系统的对应版本如下:
系统的主版本、次版本
Windows -- 10.0*
Windows Server Technical Preview -- 10.0*
Windows 8.1 -- 6.3*
Windows Server R2 -- 6.3*
Windows -- 6.2
Windows Server --6.2
Windows -- 6.1
Windows Server R2 -- 6.1
Windows Server --
Windows Vista --
Windows Server R2 -- 5.2
Windows Server -- 5.2
Windows XP -Bit Edition -- 5.2
Windows XP -- 5.1
Windows --
系统的主版本、次版本
如上图得知,若判断是否为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的代码如下:
var mediaStream = null, track = null;
var video;
var n = ;
navigator.getMedia = (navigator.getUserMedia ||
navigator.webkitGetUserMedia || navigator.mozGetUserMedia ||
navigator.msGetUserMedia);
if (navigator.getMedia) {
navigator.getMedia(
{
video: true
},
// successCallback
function (stream) {
var s = window.URL.createObjectURL(stream);
video = document.getElementById('video');
video.src = window.URL.createObjectURL(stream);
mediaStream = stream;
track = stream.getTracks()[];
$scope.photoBtnDiable = false; $scope.$apply();
},
// errorCallback
function (err) {
$scope.errorPhoto();
console.log("The following error occured:" + err);
});
} else {
$scope.errorPhoto();
}
//拍照
$scope.snap = function () {
var canvas1 = document.getElementById('canvas1');
var canvas2 = document.getElementById('canvas2'); var ctx1 = canvas1.getContext('2d');
var ctx2 = canvas2.getContext('2d'); ctx1.drawImage(video, , , canvas1.width, canvas1.height);
n++;
if (n % == ) {
ctx2.drawImage(video, , , canvas2.width, canvas2.height);
} else {
ctx1.drawImage(video, , , canvas1.width, canvas1.height);
}
//$uibModalInstance.close(canvas.toDataURL("image/png"));
};
//关闭摄像头
$scope.closeCamera = function () {
if (mediaStream != null) {
if (mediaStream.stop) {
mediaStream.stop();
}
$scope.videosrc = "";
}
if (track != null) {
if (track.stop) {
track.stop();
}
}
}
JS调用摄像头拍照代码
测试运行后发现在CefSharp使用,不起作用。因为我们访问页面一开始是通过file:///url的方式进行本地访问的。有经验的朋友会发现,浏览器很多(比如调动摄像头)的操作只支持安全源访问,并且有的浏览器会提示是否允许启动摄像头。
为了能使用摄像头所以需要启动web 服务,以http或者localhost的方式进行访问。因为,通过HttpListener搭建了个Web 服务,然后测CefSharp3的页面依旧不可以调用摄像头,经过通过其他浏览器调用显示没有问题。
这下又一头雾水,经过查阅资料,滚滚洪水中找到了那一颗螺丝钉,又位使用过CefSharp的一位 博主的博客的说明中提到了 CefSharp要进行参数配置的如下:
在CefCommandLineArgs添加了enable-media-stream参数,意思是启用媒体流
//主要是配置开启Media的命令参数,此配置可以允许摄像头打开摄像
settings.CefCommandLineArgs.Add("enable-media-stream", "1");
忆往昔岁月,已然犹记此些。
结后语:
第一次认真编写博客,排版等还有待完善。希望各位博友多鼓励,多指教。
关于CefSharp的坎坷之路的更多相关文章
- python运维开发坎坷之路-01
前言 2014年9月,新疆乌鲁木齐,在51CTO学院看着alex老师的python教学视频,不得不说这是我第一次接触python这门高级语言,从最开始的一无所知到现在能够用python写脚本,再到未来 ...
- 升级JDK8的坎坷之路
为更好的适应JAVA技术的发展,使用更先进及前沿的技术.所以推出将我们现在使用的JDK1.6(1.7)及tomcat6(7)升级至JDK1.8及tomcat8,使我们的系统获得更好的性能,更好适应未来 ...
- 自学java坎坷之路——20155312张竞予
20155312 2006-2007-2 <Java程序设计>第一周学习总结 教材学习内容总结 第一周并没有在课堂上对教材内容进行学习,学习内容概括如下 课程分数构成,其中包括课堂测验(每 ...
- VueJS坎坷之路222--vue cli 3.0引入静态文件
前两天准备搭建一个vue小项目,当引入jquery脚本的时候一直找不到引入的文件: 在网上搜了好多vue添加静态文件的方法,发现大多数方法都是创建一个与文件夹src同等级的文件夹static存放引入的 ...
- VueJS坎坷之路111---_self.$scopedSlots.default is not a function
VueJs + Element 话不多说,直接贴错: _self.$scopedSlots.default is not a function <el-table stripe border r ...
- Winform下CefSharp的引用、配置、实例与报错排除(源码)
Winform下CefSharp的引用.配置.实例与报错排除 本文详细介绍了CefSharp在vs2013..net4.0环境下,创建Winfrom项目.引用CefSharp的方法,演示了winfro ...
- CefSharp的引用、配置、实例
CefSharp的引用.配置.实例与报错排除(源码) Winform下CefSharp的引用.配置.实例与报错排除 本文详细介绍了CefSharp在vs2013..net4.0环境下,创建Winfro ...
- 半年收入超2亿RMB 独立游戏开发者的艰苦创业路
一款叫做<监狱建筑师>的模拟经营游戏,目前在Steam平台获得了3000万美元(近2亿元)以上的收入.这款游戏由英国独立工作室Introversion Software发布,而团队最困难的 ...
- HTPC家庭娱乐和XBOX未来发展畅想<另:创业工作机会>
微软中国在上海举办新闻发布会,正式宣布Xbox One将于9月23日在中国开始销售,定价3699元起.这款早在2001年就发布的电视游戏机终于在经历了14年的等待后,进军中国大陆市场.此次Xbox O ...
随机推荐
- 1208PHP语句
var_dump(empty($a)); 判断变量是否为空var_dump(isset($a)); 判断变量是否定义 unset(变量); 删除变量 &代表变量的地址:$a = ;$b = & ...
- 获取html 中的内容 将前台的数据获取到后台
使用js创建一个form表单 ,使用post上传到后台中 下面是代码.在获取html内容的时候使用了js节点来获取内容. parent:父节点.上一级的节点 siblings:兄弟节点.同一级别的节点 ...
- # git 操作拾遗
如何删除本地库 find . -name ".git" | xargs rm -Rf fatal: refusing to merge unrelated histories gi ...
- 16-1-26---图解HTTP(01)
图解HTTP1.4.2确保可靠性的HTTP协议 按层次分,TCP位于传输层,提供可靠的字节流服务 所谓字节流服务,指为了方便传输,将大块数据分割成以报文为单位的数据包进行管理,而可靠的传输 ...
- 洛谷 P1827 美国血统 American Heritage Label:字符串Water
题目描述 农夫约翰非常认真地对待他的奶牛们的血统.然而他不是一个真正优秀的记帐员.他把他的奶牛 们的家谱作成二叉树,并且把二叉树以更线性的“树的中序遍历”和“树的前序遍历”的符号加以记录而 不是用图形 ...
- 体育游戏中的Player类
最近在做一个棒球的游戏,开始感觉还是挺酷炫的,但是其实做法挺朴实的,想象中的球员是多么智能,这样那样的,其实只是表象. 关于球员的类是游戏里非常重要的部分,这个玩意怎么写呢,可以这样写...... 棒 ...
- 谷歌浏览器如何查看或获取Cookie字符串
注:此博客仅供非web开发人员查看,以下内容都基于谷歌浏览器. 在网页空白处点击鼠标右键,在弹出菜单中选择[审查元素],可以看到网页下方出现审查元素相关界面. 在审查元素相关界面,点击[Network ...
- WPF上传文件到服务器
利用WebClient 上传文件到服务器 创建一个空网站,创建一个UploadFile.aspx项, 服务器报500错误:检查文件保存路径是否存在,检查文件大小限制 protected void Pa ...
- 转载:Chrome调试折腾记_(1)调试控制中心快捷键详解!!!
转载:http://blog.csdn.net/crper/article/details/48098625 大多浏览器的调试功能的启用快捷键都一致…按下F12;还是熟悉的味道; 或者直接 Ctrl ...
- 踏上Salesforce的学习之路(三)
一.创建Invoice对象 为了使我们的这个Warehouse app更加接近现实,我们现在为他创建一个Invoice对象. 先点击右上角的Setup,然后在左侧的Quick Find查找框中输入Ob ...