浏览器扩展系列————异步可插入协议(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 ...
随机推荐
- 【Bootstrap】自己主动去适应PC、平面、手机Bootstrap网格系统
酒吧格英语作为一门系统"grid systems",也有人翻译成"网络格系统".使用固定格子设计布局,其风格整齐而简洁,在二战结束后人气,流风格之中的一个. 1 ...
- 探索C/C++大数快(自然数)模板
本文fcbruce个人原创整理.转载请注明出处http://blog.csdn.net/u012965890/article/details/40432511,谢谢. 我们知道在C/C++中int型可 ...
- DataTable填补了实体类返回泛型集合
坤哥见我昨天找了一段代码,如下面: 略微解释下,这段代码时D层查询结束后,将datatable查询到的结果赋值给实体对象的属性,然后返回实体的过程.坤哥看了之后问我,假设实体有500多个属性,难道也要 ...
- CSS——(2)与标准流盒模型
部分博客<CSS--(1)基础>中简介了CSS的概念和几种用法,如今主要是介绍其的核心内容. 盒子模型 为了理解盒子模型,我们能够先从生活中的盒子入手.盒子是用来放置物品的,内部除了有物品 ...
- CSDN上看到的一篇有关Spring JDBC事务管理的文章(内容比较全) (转)
JDBC事务管理 Spring提供编程式的事务管理(Programmatic transaction manage- ment)与声明式的事务管理(Declarative transaction ma ...
- UVa 353 - Pesky Palindromes
称号:字符串统计回文子的数量. 分析:dp,暴力.因为数据是小,直接暴力可以解决. 说明:(UVa最终评出800该). #include <iostream> #include <c ...
- File类基本操作之OutputStream字节输出流
贴代码了,已经測试,可正常编译 package org.mark.streamRW; import java.io.File; import java.io.FileOutputStream; imp ...
- hdu 3076 ssworld VS DDD (概率dp)
///题意: /// A,B掷骰子,对于每一次点数大者胜,平为和,A先胜了m次A赢,B先胜了n次B赢. ///p1表示a赢,p2表示b赢,p=1-p1-p2表示平局 ///a赢得概率 比一次p1 两次 ...
- linux添加到普通用户sudo才干
在超级用户模式添加到普通用户sudo才干 1. su -(进root用户) 2. chmod u+w /etc/sudoer 3. vim /etc/sudoers 于root ALL=(ALL) A ...
- 使用shell命令分析统计日志
用户需要登录统计信息,当分析用户行为,使用shell通常可以很容易地取出了大量的数据.删除,然后放入excel统计. 例如:统计日志含有loadCustomProcess这个地址的訪问,按訪问耗时排序 ...