浏览器扩展系列————异步可插入协议(pluggable protocol)的实现
原文:浏览器扩展系列————异步可插入协议(pluggable protocol)的实现
IE中有很多我们比较熟悉的协议,如http,https,mailto,ftp等。当然你也可以实现自己定义的协议,稍微谈一下这里所说的协议,从我的理解来说这里的协议只有当你的网页引用某个资源时才会调用,而不是随便在某个属性的值前面加上某个协议的名称就可以了。常见的协议调用如img的src属性中,很多元素style中的background-image属性中,还有a标签的href属性中。
言归正传,前面说到的实现自定义协议就用到了一种IE下异步可插入协议的技术。
从分类上来说,这种异步可插入协议的技术还分为两种:
- 永久的异步可插入协议,就像http,https,mailto这种不论在ie中或是其它用到浏览器控件中使用。
- 临时的异步可插入协议,只能用在某个进程内,用完可以擦除。
更详细介绍异步可插入协议的资源有http://www.cppblog.com/bigsml/archive/2008/03/23/45145.html。
因为网上介绍永久的异步可插入协议的资源还很多,如codeproject上的:
这篇就主要谈谈如何实现临时的异步可插入协议的方法。
下面谈下具体的实现。
在本实现中主要用到了下面这几个接口:
- IInternetProtocol
- IInternetProtocolRoot
- IInternetSession
- IInternetProtocolInfo
IInternetProtocol接口
它有四个方法:
|
LockRequest |
Locks the requested resource so that the IInternetProtocolRoot::Terminate method can be called, and the remaining data can be read. |
|
Read |
Reads data that the pluggable protocol handler gets. |
|
Seek |
Moves the current seek offset. |
|
UnlockRequest |
Frees any resources associated with a lock. |
主要用于下载资源,将处理后的资源传递给IE进行显示。
IInternetProtocolRoot接口
|
Abort |
Cancels an operation that is in progress. |
|
Continue |
Enables the pluggable protocol handler to continue processing data on the apartment thread. |
|
Resume |
Not currently implemented. |
|
Start |
Starts the operation. |
|
Suspend |
Not implemented. |
|
Terminate |
Releases the resources used by the pluggable protocol handler. |
主要用于解析资源,准备待下载的资源。
IInternetSession接口
它包括9个方法,根据需要我们只用到了下面两个方法:
|
RegisterNameSpace |
Registers a temporary pluggable namespace handler on the current process. |
|
UnregisterNameSpace |
Unregisters a temporary pluggable namespace handler. |
实现临时可插入协议的注册和取消。
IInternetProtocolInfo接口
它包括4个方法。
|
CombineUrl |
Combines a base URL and relative URL into a full URL. |
|
CompareUrl |
Compares two URLs and determines if they are equal. |
|
ParseUrl |
Parses a URL. |
|
QueryInfo |
Gets information related to the specified URL. |
主要提供了对于Url的处理。
此外,在构造IInternetSession的时候还用到了一个外部方法:
[DllImport("urlmon.dll")]
private
static
extern
void CoInternetGetSession(int sessionMode,
out
IInternetSession session, int reserved);
预备的知识介绍完,下面就是具体实现了。
一般方法是在一个类中实现IInternetProtocol,IInternetProtocolRoot,IInternetProtocolInfo三个接口,然后通过IInternetSession接口的RegisterNameSpace方法来注册这个自定义协议,用完这后再调用UnregisterNameSpace方法来注销这个自定义协议。
关于IE和IInternetProtocol,IInternetProtocolRoot,IInternetProtocolInfo三个接口的调用流程可以参考msdn上的介绍,中文版的翻译可以参考:
http://www.cnblogs.com/volnet/archive/2008/03/28/About_Asynchronous_Pluggable_Protocols.html
首先通过CoInternetGetSession方法得到一个IInternetSession对象,然后注册自定义的协议:
IInternetSession session;
CoInternetGetSession(0, out session, 0);
Guid guid = new
Guid("79EAC9E4-BAF9-11CE-8C82-00AA004BA90B");
session.RegisterNameSpace(new
ClassFactory(), ref guid, ProcotolName, 0, null, 0);
在注册的时候要传入一个实现了IClassFactory接口的对象,下面是对次接口的实现:
// Interface IClassFactory is here to provide a C# definition of the
// COM IClassFactory interface.
[
ComImport, // This interface originated from COM.
ComVisible(true), // It is not hard to imagine that this interface must not be exposed to COM.
InterfaceType(ComInterfaceType.InterfaceIsIUnknown), // Indicate that this interface is not IDispatch-based.
Guid("00000001-0000-0000-C000-000000000046") // This GUID is the actual GUID of IClassFactory.
]
public
interface
IClassFactory
{
void CreateInstance(IntPtr pUnkOuter, ref
Guid riid, out
IntPtr ppvObject);
}
[ComVisible(true)]
public
class
ClassFactory : IClassFactory
{
#region IClassFactory Implementations
public
void CreateInstance(IntPtr pUnkOuter, ref
Guid riid, out
IntPtr ppvObject)
{
ppvObject = Marshal.GetComInterfaceForObject(new
MyImageProtocol(), typeof(IInternetProtocolInfo));
}
#endregion
}
一下至于IInternetProtocol,IInternetProtocolRoot,IInternetProtocolInfo三个接口实现,大家可以参考上面提到的http://www.cnblogs.com/volnet/archive/2008/03/28/About_Asynchronous_Pluggable_Protocols.html这篇文章。不过要注意的就是这个实现的第二个协议似乎有bug,在实验一次后,可能将IE搞崩溃了,所以实验时要谨慎,不行就用regasm /u命令将dll注销了。
浏览器扩展系列————异步可插入协议(pluggable protocol)的实现的更多相关文章
- 浏览器扩展系列————在WPF中定制WebBrowser快捷菜单
原文:浏览器扩展系列----在WPF中定制WebBrowser快捷菜单 关于如何定制菜单可以参考codeproject上的这篇文章:http://www.codeproject.com/KB/book ...
- 浏览器扩展系列————给MSTHML添加内置脚本对象【包括自定义事件】
原文:浏览器扩展系列----给MSTHML添加内置脚本对象[包括自定义事件] 使用场合: 在程序中使用WebBrowser或相关的控件如:axWebBrowser等.打开本地的html文件时,可以在h ...
- Chrome浏览器扩展开发系列之十四
Chrome浏览器扩展开发系列之十四:本地消息机制Native messaging 时间:2015-10-08 16:17:59 阅读:1361 评论:0 收藏:0 ...
- Chrome浏览器扩展开发系列之十四:本地消息机制Native messagin
Chrome浏览器扩展开发系列之十四:本地消息机制Native messaging 2016-11-24 09:36 114人阅读 评论(0) 收藏 举报 分类: PPAPI(27) 通过将浏览器 ...
- Chrome浏览器扩展开发系列之十六:扩展中可用的Chrome浏览器API
除了Chrome浏览器支持的chrome.* API之外,Chrome浏览器扩展还可以使用Chrome浏览器为Web页面或Chrome app提供的APIs.对于Chrome浏览器2支持的API,还可 ...
- Chrome浏览器扩展开发系列之十四:本地消息机制Native messaging
通过将浏览器所在客户端的本地应用注册为Chrome浏览器扩展的“本地消息主机(native messaging host)”,Chrome浏览器扩展还可以与客户端本地应用之间收发消息. 客户端的本地应 ...
- Chrome浏览器扩展开发系列之十九:扩展开发示例
翻译总结了这么多的官网内容,下面以一款博主开发的“沪深股票价格变化实时追踪提醒”软件为例,介绍Chrome浏览器扩展程序的开发,开发环境为Eclipse IDE+Chrome Browser. “沪深 ...
- Chrome浏览器扩展开发系列之十八:扩展的软件国际化chrome.i18n API
i18n是internationalization 的简写,这里将讨论软件国际化的问题.熟悉软件国际化的朋友应该知道,软件国际化要求,页面中所有用户可见的字符串都必须置于资源属性文件中.资源属性文件中 ...
- Chrome浏览器扩展开发系列之十七:扩展中可用的chrome.events API
chrome.events中定义了一些常见的事件类型,可以供Chrome浏览器扩展程序发出对应的事件对象. 对于关注的事件,首先要通过addListener()在对应的事件上注册监听器,示例如下: c ...
随机推荐
- LeetCode——ZigZag Conversion
The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like ...
- Jenkins(二) 安装、新建Jobs与删除及SVN配置(转)
官网首页(https://jenkins-ci.org/)就提供了windows版本的Jenkins安装包.可以自己下载一个用于学习.安装后自动打开http://localhost:8080,就可以看 ...
- DOM对象本身也是一个js对象,所以严格来说,并不是操作这个对象慢,而是说操作了这个对象后,会触发一些浏览器行为(转)
一直都听说DOM很慢,要尽量少的去操作DOM,于是就想进一步去探究下为什么大家都会这样说,在网上学习了一些资料,这边整理出来. 首先,DOM对象本身也是一个js对象,所以严格来说,并不是操作这个对象慢 ...
- MongoDB CRUD 基础知识
建立一个良好的发展环境 环境win8 x64,下载并安装省略.经mongodb 的bin文件夹增加windows的path中,为以后使用方便. c盘新建存储目录:c:/data/db 执行服务:WIN ...
- 在Repeater控件中使用if语句
原文:在Repeater控件中使用if语句 .Afr_ARTICLE_TITLE { font: NORMAL BOLD 14px "Tahoma"; } .Afr_CONTENT ...
- AFNetworking框架_上传文件或图像server
的文本 XXXXXXXXXX在自己的论点更填写 - (void)uploadImageWithImage:(NSString *)imagePath { //上传其它所需參数 NSString *us ...
- Python补充04 Python简史
原文:Python简史 作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! Python是我喜欢的语言,简洁,优美,容易使用.前两天, ...
- 使用Java中间MessageDigest该文本MD5加密(Java中间MD5样品加密算法演示)
原文地址:http://www.wenboxz.com 版权声明:本文博客原创文章,博客,未经同意,不得转载.
- Android 在非主线程无法操作UI意识
Android在应用显示Dialog是一个非常easy事儿,但我从来没有尝试过Service里面展示Dialog. 经验UI操作要在主线程,本地的服务Service是主线程里没错,可是远程servic ...
- k8s google sample - guestbook
Redis读写分离作为存储 PHP网页作为前端 github地址 https://github.com/kubernetes/kubernetes/blob/release-1.1/examples/ ...