此文已由作者严跃杰授权网易云社区发布。
欢迎访问网易云社区,了解更多网易技术产品运营经验。
主要参考微信网页版
和网易邮箱插件
考虑到操作方便性,保留截图窗口右下角的鼠标操作按钮,暂不开发画图和文字功能。
分析插件需要完成主要工作如下
1、 鼠标点击网页截屏按钮,网页调用插件开放js接口生成全屏窗口覆盖整个桌面,窗口背景为暗色的原桌面图片。
2、 鼠标在窗口任意位置按下左键拖动,在窗口上绘制一块亮色的选择区块。
3、 鼠标左键抬起后,右下角出现按钮框或者更改左上角提示。
4、 鼠标左键选中选择区块后,可拖动该区块;鼠标选中区块边缘后拖动可更改区块大小。
5、 鼠标双击该区块或按右下角确定按钮后生成区块的内存位图。
6、 将该内存位图转换为png图片。
7、 将改png图片通过https接口上传,并获取远端可访问地址。
8、 通过回调接口通知web页面该图片地址
网易邮箱插件使用的是gears框架
框架大而全较为复杂,学习成本高。
google已经停止对gears的开发
firebreath是一个专门的插件框架
domo和文档较全,学习成本相对较低。
通过firebreath主页的文档
http://www.firebreath.org/display/documentation/FireBreath+Home
可以快速掌握如何创建一个插件,包括项目创建,编译生成,部署及测试。
1. 截屏实现原理比较简单,但是从头写还是比较费时间的。从网上找到一个带源码的截屏应用http://www.cppblog.com/shly/archive/2011/10/07/157704.html, 运行起来后是这样的, 初步能满足要求。
我们对代码稍作修改,并打包成静态库,以便调用。
2. Bmp转png功能,需要libpng,zlib,boost(firebreath内有),引用了邮箱助手内转换代码。
3. https图片上传。
基于libcurl实现https上传,但是libcurl默认是不支持ssl,因此先后编译openssl和libcurl,使其支持https。
编译openssl生成静态库libeay32.lib, ssleay32.lib,参考
http://blog.163.com/xiaoting_hu/blog/static/50464772201310415042524/
编译libcurl生成静态库libcurl.lib, 参考
http://blog.csdn.net/haiyan_qi/article/details/23608037
注意编译libcurl时要在预处理器定义中加入
BUILDING_LIBCURL
USE_OPENSSL
USE_SSLEAY
最后创建一个上传文件的项目,并按照libcurl文档说明完成上传功能开发,最后打包成静态库以便调用。注意因为该项目要引用libcurl静态库,预处理器定义中加入CURL_STATICLIB,否则会报错。
1. 把上述资源组织起来,项目文件夹结构如下:
2. 把外部项目加入firebreath中我们自己创建的插件项目内有两种方式
1) 用vs打开插件解决方案后,直接在添加其他引用项目,习惯用vs的人一般都会这么干,但是这里不推荐这么做。原因是如果需要更新插件版本,我们需要重新执行cmake生成插件项目和解决方案,这会导致通过vs做的配置丢失,需要重新配置。
2) 在cmake文件中添加引用项目(推荐)
生成项目结构如下,把BmpToPng/HttpUpload/PrintScreen等这些项目加载到解决方案中,主要是为了方便对这些功能模块进行开发和调试。
完成对各功能模块开发和验证后,将其配置到YiXinPlugin插件项目。接下来就是jsapi的开发,能够让jsapi正确调用上述功能模块提供的外部接口,以完成需求分析中所描述到的功能。
3. 代码类图结构如下:
绿色表示Firebreath/atl接口类;
淡蓝色表示firebreath为插件项目扩展的接口类,这里定义了所有对外开放jsapi,也是实现插件所有的功能入口;
黄色是需要自己实现的功能模块。
1. IE/chrome浏览器页面调用jsapi后,可以完成截图和上传功能,但是上传过程中浏览器无法响应用户操作
分析:IE/chrome会在ui线程中调用firebreath jsapi, 该api会调用CaptureScreenAPP::printscreen和HttpUpload::upload函数,这两个函数都会阻塞该api接口返回,导致浏览器ui线程无响应。由于在CaptureScreenAPP::printscreen阶段,浏览器被截屏窗口覆盖,所以这时掩盖了浏览器无法响应用户输入的问题,但一旦截屏完成截屏窗口随即销毁,线程进入HttpUpload::upload阶段,明显发现该问题。解决方法:创建独立线程运行HttpUpload::upload,解决上传阶段浏览器无影响的问题。
2. Firefox奔溃问题
问题描述:firefox通过页面调用jsapi后,插件创建了截屏窗口,但是鼠标点击该窗口无反应,几秒钟后firefox提示插件无响应,随后奔溃。IE和chrome没有问题。
分析:问题原因同问题1,估计是浏览器实现的差异导致该该问题,修改为CaptureScreenAPP::printscreen也放到独立线程中运行,这个更改保证了jsapi即时返回。但也引出下面第三个问题。
3. 截屏窗口出现时被浏览器窗口挡住问题
该问题在IE/Chrome/Firefox同时出现,如下
点击页面按钮调用插件提供的jsapi后,浏览器始终保持为顶层窗口,截屏窗口被浏览器窗口覆盖。
分析:CaptureScreenAPP::printscreen在独立线程中运行,该函数中创建窗口父窗口被设置为NULL,因此在调用SetWindowPos将窗口设置为HWND_TOPMOST,无法将截屏窗口设置到浏览器窗口前。
解决方法:将截屏窗口父窗口设置为浏览器窗口。
4. 插件在IE下运行,第一次出现截屏窗口是,alt+tab导致窗口切换的问题
问题描述:经过问题三的修改,发现在IE下,第一次点击截屏按钮,IE浏览器窗口仍然保持在截屏窗口前,而且alt+tab可以切换到其他窗口。Chrome/firefox没有问题。
解决方案:
在截屏窗口显示前,调用SetForegroundWindow(g_MainDlg.m_hWnd);将截屏窗口设置为前置窗口,这能解决第一次截屏窗口出现时被IE覆盖的问题。但无法解决alt+tab切换问题;通过截获截屏窗口的MSG_WM_KILLFOCUS事件,在截屏窗口失去焦点时调用SetWindowPos设置为前置窗口,保证不被切换到其他窗口。
Firebreath可以生成msi,也可以通过配置为各浏览器生成cab,crx,xpi格式插件,当然你也可以自己创建。
IE发布
在IE发布cab需要对cab进行数字签名,如下介绍了如何生成自己证书及签名,如果需要对外发布,则需要购买正是CA证书。
http://hiyyp1234.blog.163.com/blog/static/67786373201261891538299/
chrome发布,如何生成crx
创建一个manifest.json文件,格式参考如下
https://developer.chrome.com/extensions/manifest
我们插件manifest.json文件如下
{ "manifest_version": 2, "name": "YiXinPlugin", "description": "YiXinPlugin by NetEase", "version": "1.0", "permissions": [ "https://web.yixin.im/", "http://10.240.155.226/" ], "plugins": [ { "path": "npYiXinPlugin.dll", "public": true} ] }
将生成的.dll文件和上述manifest.json放到同一个文件夹下,打开chrome://externsion页面,选中开发者模式后点击打包扩展程序,如下
然后对话框选中文件夹,打包后生成.crx和.pem两个文件。保留好.pem,下次打升级包时需要用到。
由于安全问题google限制了用户私自分发crx,强制要求将extension提交到web app store才能让用户web页面上进行下载安装。有两个方案:
1. 按照google要求将extension发布到web app store.流程如下 (更新:该方法不可用)
https://developer.chrome.com/webstore/publish
备注:google目前已限制基于npapi插件,不允许其发布到web app store. 详细请参见
http://blog.chromium.org/2013/09/saying-goodbye-to-our-old-friend-npapi.html
2. 私自发布的crx可以让用户在chrome://extension页面进行安装,google目前未对此作限制。
Firefox发布,如何生成xpi插件
详细打包流程参考
https://developer.mozilla.org/en-US/docs/Building_an_Extension
最简要的打包一个npapi插件扩展如下:
创建如下一个目录结构:
yixinplubin_firefox |--plugins |-- npYiXinPlugin.dll |-- install.rdf
Intall.rdf内容如下
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:em="http://www.mozilla.org/2004/em-rdf#"> <Description about="urn:mozilla:install-manifest"> <em:id>helloween@myplugin.org</em:id> <em:name>yixinplugin</em:name> <em:version>1.0.0.1</em:version> <em:targetApplication> <Description> <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id> <em:minVersion>4.0</em:minVersion> <em:maxVersion>30.0</em:maxVersion> </Description> </em:targetApplication> <em:unpack>true</em:unpack> </Description> </RDF>
然后将plugins和install.rdf压缩至.zip,将压缩包后缀更改为.xpi即可。
Xpi同样需要数字签名,否则安装会出告警。签名方法参考如下:
https://developer.mozilla.org/en-US/docs/Signing_a_XPI
网易云免费体验馆,0成本体验20+款云产品!
更多网易技术、产品、运营经验分享请点击。
相关文章:
【推荐】 中文脏话识别的解决方案
【推荐】 react技术栈实践(2)
【推荐】 Hive中文注释乱码解决方案