原文:浏览器扩展系列————异步可插入协议(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. 求Sn=a+aa+aaa+…+aa…aaa(有n个a)…

    时间限制: 1 Sec  内存限制: 128 MB 提交: 352  解决: 174 [提交][状态][讨论版] 题目描述 求Sn=a+aa+aaa+-+aa-aaa(有n个a)之值,其中a是一个数字 ...

  2. 【网络流量最大流量】poj3281Dining

    /* EK算法版本号,哦,慢.....见下文dinic版本号 ----------------------------------------- 最大的问题是网络流量问题 -------------- ...

  3. java流的性能优化1-文件复制

    传统的I/O速度相对照较慢,它会成为系统性能的瓶颈,所以在java1.4之后提供了NIO,它是一种全新的流:它具有下面特性: 1.为全部的原是类型提供Buffer缓存支持: 2.使用java.nio. ...

  4. 使用SQLServer Audit来监控触发器的启用、禁用情况

    原文:使用SQLServer Audit来监控触发器的启用.禁用情况 使用情景: 有时候会发现在触发器中的业务逻辑没有执行,可能是因为触发器的逻辑错误所引起的.但是有时候却是因为一些触发器被禁用了. ...

  5. Unity3d C# Socket 下载文件 (同步到)

    续篇 Unity3d C# HttpWebRequest 异步下载文件 ,由于project编译为IL2CPP的情况下仍然无效.提示HttpWebrequest 在当前版本号不支持.所以还是寻求其他的 ...

  6. iostream与iostream.h乱弹琴

    #include <iostream.h> 非标准输出流 #include <iostream>    标准输出流 见短eclipse关于使用android ndk时的简单代码 ...

  7. 左右 Java 于 finally 深度分析语句块

    首先,让我们来问你一个问题:finally 声明块将运行? 很多人认为 finally 语句块是一定要运行.其中还包括了一些非常有经验的 Java 程序猿.不幸的是,没有像很多像人们想象,对于这个问题 ...

  8. 【J2SE】java实现简单照片查看器

    程序执行结果: project结构图: 程序代码: import java.awt.BorderLayout; import java.awt.FileDialog; import java.awt. ...

  9. HDU-4628 Pieces 如压力DP

    鉴于他的字符串,每一个都能够删除回文子串.子可以是不连续,因此,像更好的模拟压力.求删除整个字符串需要的步骤的最小数量. 最大长度为16,因此不能逐行枚举状态.首先预处理出来全部的的回文子串,然后从第 ...

  10. Windows下一个SlikSVN使用

    我相信所有的应SVN不熟悉.使用过.可是并非人人都自己配置过SVNserver.以下就是我配置SVNserver的步骤.以及在配置过程中碰见的一些问题,在此记录,希望对你有所帮助. 安装 双击执行&q ...