原文:浏览器扩展系列————异步可插入协议(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上的:

http://www.cppblog.com/bigsml/archive/2008/03/23/45145.html

http://www.codeproject.com/KB/aspnet/AspxProtocol.aspx

这篇就主要谈谈如何实现临时的异步可插入协议的方法。

下面谈下具体的实现。

在本实现中主要用到了下面这几个接口:

  • 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)的实现的更多相关文章

  1. 浏览器扩展系列————在WPF中定制WebBrowser快捷菜单

    原文:浏览器扩展系列----在WPF中定制WebBrowser快捷菜单 关于如何定制菜单可以参考codeproject上的这篇文章:http://www.codeproject.com/KB/book ...

  2. 浏览器扩展系列————给MSTHML添加内置脚本对象【包括自定义事件】

    原文:浏览器扩展系列----给MSTHML添加内置脚本对象[包括自定义事件] 使用场合: 在程序中使用WebBrowser或相关的控件如:axWebBrowser等.打开本地的html文件时,可以在h ...

  3. Chrome浏览器扩展开发系列之十四

    Chrome浏览器扩展开发系列之十四:本地消息机制Native messaging 时间:2015-10-08 16:17:59      阅读:1361      评论:0      收藏:0    ...

  4. Chrome浏览器扩展开发系列之十四:本地消息机制Native messagin

    Chrome浏览器扩展开发系列之十四:本地消息机制Native messaging 2016-11-24 09:36 114人阅读 评论(0) 收藏 举报  分类: PPAPI(27)  通过将浏览器 ...

  5. Chrome浏览器扩展开发系列之十六:扩展中可用的Chrome浏览器API

    除了Chrome浏览器支持的chrome.* API之外,Chrome浏览器扩展还可以使用Chrome浏览器为Web页面或Chrome app提供的APIs.对于Chrome浏览器2支持的API,还可 ...

  6. Chrome浏览器扩展开发系列之十四:本地消息机制Native messaging

    通过将浏览器所在客户端的本地应用注册为Chrome浏览器扩展的“本地消息主机(native messaging host)”,Chrome浏览器扩展还可以与客户端本地应用之间收发消息. 客户端的本地应 ...

  7. Chrome浏览器扩展开发系列之十九:扩展开发示例

    翻译总结了这么多的官网内容,下面以一款博主开发的“沪深股票价格变化实时追踪提醒”软件为例,介绍Chrome浏览器扩展程序的开发,开发环境为Eclipse IDE+Chrome Browser. “沪深 ...

  8. Chrome浏览器扩展开发系列之十八:扩展的软件国际化chrome.i18n API

    i18n是internationalization 的简写,这里将讨论软件国际化的问题.熟悉软件国际化的朋友应该知道,软件国际化要求,页面中所有用户可见的字符串都必须置于资源属性文件中.资源属性文件中 ...

  9. Chrome浏览器扩展开发系列之十七:扩展中可用的chrome.events API

    chrome.events中定义了一些常见的事件类型,可以供Chrome浏览器扩展程序发出对应的事件对象. 对于关注的事件,首先要通过addListener()在对应的事件上注册监听器,示例如下: c ...

随机推荐

  1. FireFox VS Chrome 之 调试篇

    一个完美的调试工具,FireBug! 精确跟踪每一步.仅仅要按下图所看到的,选择"脚本",然后在下方选择脚本所在的文件就可以对该文本的运行进行断点跟踪. 而且仅当一个线程运行结束后 ...

  2. url参数中出现+、空格、=、%、&、#等字符的解决办法

    url出现了有+,空格,/,?,%,#,&,=等特殊符号的时候,可能在服务器端无法获得正确的参数值,如何是好?解决办法将这些字符转化成服务器可以识别的字符,对应关系如下:URL字符转义 用其它 ...

  3. 真实故事:网站遭遇DOS攻击

     网站遭遇DOS攻击 一个.事件背景 长假对于IT人员来说是个短暂的休整时期,可IT系统却一时也不能停.越是节假日,越可能出大问题,以下要讲述的就是一起遭受DOS攻击的案例. 春节长假刚过完,小李 ...

  4. 【转】window.scroll 浏览器滚动条的参数总结

    如内容超出单元格,则隐藏style="TABLE-LAYOUT: fixed" 让弹出窗口总是在最上面: <body onblur="this.focus();&q ...

  5. Hybrid app 发展历程

    距离上一篇<基于微信 js-sdk 的简单应用>已经快一年了,说来真是惭愧.上次不久之后便换了工作,一直处于比较忙的状态.其次后面酣畅一段时间都没有从事移动相关的工作.直到今年3月份开始, ...

  6. 【Hibernate步步为营】--(一对多映射)之双向关联

    上篇文章讨论了单向关联的一对多映射,在一的一端维护双向的关系这样的做法尽管能实现可是存在非常多缺陷,首先生成非常多多余的SQL语句,由于多的一端不维护关系,仅仅有一的一端维护,在进行操作时一的一端会发 ...

  7. jquery :操作iframe

    原文 jquery :操作iframe 1. 内容里有两个ifame <iframe id="leftiframe"...</iframe> <iframe ...

  8. Android 设计模式Template Method模式

    自定义模板方法模式:定义的算法的骨架中的方法,虽然某些步骤推迟到子类中,下模板方法允许子类不能改变在的情况下,该算法的结构.算法重新定义某些步骤. 设计原则:不要给我们打电话.我会打电话给你.(像猎头 ...

  9. 大约 C++ 几个方面分析--overload, override, overwrite, rewrite

    overload, override, overwrite, rewrite 这几个单词常常出如今 C++ 书中,翻阅一些译版后发现并未对 override, overwrite, rewrite 严 ...

  10. 用android LinearLayout和RelativeLayout实现精确布局(转)

    先明确几个概念的区别: padding margin都是边距的含义,关键问题得明白是什么相对什么的边距. padding是控件的内容相对控件的边缘的边距. margin是控件边缘相对父控件的边距. a ...