项目背景:html
公司的XX产品须要升级和之后支持多平台的使用。由于以前项目是由WPF实现的。目前之后想做为Html5来展现页面。web
由于涉及到总体更改遇到的问题较多以及其余缘由,因此只是内部内容区域先替换为Html5页面,因此须要嵌入Browser控件。canvas
Browser控件的选型:windows
1.Winform中的WebBrowser浏览器
2.WPF中的WebBrowser安全
3.WebKit.Net服务器
4.CefSharpapp
5.awesominum框架
6.OpenWebKitSharpide
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了,以下图 位置:一、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 <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> 2 <application> 3 <!-- A list of the Windows versions that this application has been tested on and is 4 is designed to work with. Uncomment the appropriate elements and Windows will 5 automatically selected the most compatible environment. --> 6 7 <!-- Windows Vista --> 8 <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" /> 9 10 <!-- Windows 7 --> 11 <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" /> 12 13 <!-- Windows 8 --> 14 <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" /> 15 16 <!-- Windows 8.1 --> 17 <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" /> 18 19 <!-- Windows 10 --> 20 <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" /> 21 22 </application> 23 </compatibility> 24 25 <!-- Indicates that the application is DPI-aware and will not be automatically scaled by Windows at higher 26 DPIs. Windows Presentation Foundation (WPF) applications are automatically DPI-aware and do not need 27 to opt in. Windows Forms applications targeting .NET Framework 4.6 that opt into this setting, should 28 also set the 'EnableWindowsFormsHighDpiAutoResizing' setting to 'true' in their app.config. --> 29 30 <application xmlns="urn:schemas-microsoft-com:asm.v3"> 31 <windowsSettings> 32 <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware> 33 </windowsSettings> 34 </application>
自动添加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 resolved 6 settings.CefCommandLineArgs.Add("disable-gpu", "1"); 7 }
其中,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.一、windows八、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 }
测试运行后发如今CefSharp使用,不起做用。由于咱们访问页面一开始是经过file:///url的方式进行本地访问的。有经验的朋友会发现,浏览器不少(好比调动摄像头)的操做只支持安全源访问,而且有的浏览器会提示是否容许启动摄像头。
为了能使用摄像头因此须要启动web 服务,以http或者localhost的方式进行访问。由于,经过HttpListener搭建了个Web 服务,而后测CefSharp3的页面依旧不能够调用摄像头,通过经过其余浏览器调用显示没有问题。
这下又一头雾水,通过查阅资料,滚滚洪水中找到了那一颗螺丝钉,又位使用过CefSharp的一位 博主的博客 的说明中提到了 CefSharp要进行参数配置的以下:
在CefCommandLineArgs添加了enable-media-stream参数,意思是启用媒体流
//主要是配置开启Media的命令参数,此配置能够容许摄像头打开摄像 settings.CefCommandLineArgs.Add("enable-media-stream", "1");
忆往昔岁月,已然犹记此些。
结后语:
第一次认真编写博客,排版等还有待完善。但愿各位博友多鼓励,多指教。