2008年3月28日星期五

看看这个“指飘器”,可没少写代码……

可爱的“指飘器”光荣测试,很庆幸在Google这个页面中还是很不错滴……

2008年3月27日星期四

[翻译]注册协议(Register Protocol)

原文链接http://kb.mozillazine.org/Register_protocol

协议是一个用来通过连接来发送、接收和处理信息的方法。普通常见的浏览器协议包括http、https、ftp和mailto。为了你能够发送一个指定的协议来查看信息,你必须注册它们。如果你输入一个未知协议(如foo)的URL在你的定位符工具栏中,你将接收到一个这样的消息:“FireFox不知道如何打开这个地址,因为协议(foo)并不关联于任何程序或者在Mozilla Suite/SeaMonkey中,foo不是一个已经注册的协议”。(译注1)

一旦注册,协议就可以用你指定的程序进行处理,就像你的浏览器或者第三方的阅读器。这意味着一个超级链接(例如:foo://fred)可以使用协议foo来打开文件fred。(译注2)

内容:(以下链接指向原文)

[hide]

 

Windows

在Windows中,协议注册时写入操作系统的。例如,当你设置一个网页浏览器为默认浏览器,操作系统将注册http、https和ftp协议并且将它们关联到这个网页浏览器;当你在邮件消息或者一个互联网快捷方式中打开http、https和ftp链接的时候,这个URL将通过这个网页浏览器来打开。相似的,当你设置默认的邮件客户端,操作系统将注册mailto协议,以至于在浏览器中打开mailto链接的时候会打开这个关联的邮件应用程序。

注意: Mozilla Suite/SeaMonkey integrates mail and browser functions以至于一个邮件消息的网页链接(例如:http://链接)将在SeaMonkey浏览器窗体中打开,“mailto:”链接将在SeaMonkey Mail中打开,而不管操作系统中协议处理器的相关设置。

其他协议可以通过配置一个安装的程序被注册为关联到一个外部应用程序来处理相关内容。例如:你可以通过RealPlayer的“偏好”->“内容”->“媒体类型”设置为RTSP URLs注册相关的处理器为RealPlayer(Real-Time Streaming Protocol)。接下来当你再次打开rtsp://链接的时候,Firefox或者Mozilla Suite/SeaMonkey将在应用程序启动前询问你是否确定这个外部的协议请求。(译注3)

同样也可以通过创建一个像下面这样的.reg文件来注册协议,将它们改成文件:

REGEDIT4

[HKEY_CLASSES_ROOT\foo]
@="URL:foo Protocol"
"URL Protocol"=""

[HKEY_CLASSES_ROOT\foo\shell]

[HKEY_CLASSES_ROOT\foo\shell\open]

[HKEY_CLASSES_ROOT\foo\shell\open\command]
@="\"C:\\Program Files\\Application\\program.exe\" \"%1\""


将foo替换为你指定的希望运行的程序C:\\Program Files\\Application\\program.exe。


注意:两个反斜干(\\)以及转义的引号(\")不应该被替换(必须的)。保存文件,然后双击它们以让他们插入Windows注册表。看看附加信息《Registering an Application to a URL Protocol


 


Linux和Mac


输入about:config到地址栏并敲入回车。



右键->新建->布尔->名字:网络.协议.处理器.外部.foo->值->true(用你指定的协议还原foo)



(英文版)Right-click -> New -> Boolean -> Name: network.protocol-handler.external.foo -> Value -> true (Replacing foo with the protocol you're specifying)



右键->新建->字符->名字:网络.协议.处理器.应用.foo->值->/path/to/app(用你指定的协议还原foo,并且path/to/app部分用你希望执行的应用程序路径来替换)



(英文版)Right-click -> New -> String -> Name: network.protocol-handler.app.foo -> Value -> /path/to/app (Replacing foo with the protocol you're specifying and /path/to/app with the path to the application you want to run.



确保network.protocol-handler.expose-all设置为true。(译注4)



 



解决纷争



(Linux和Mac)如果设置偏好的时候路径或者名字不正确,FireFox将显示错误为:“协议(foo)没有与任何程序关联。”(bug 312953)



如果你在Firefox使用mailto协议没有关联任何程序,请重新设置你的默认邮件客户端(default mail client.)。



默认情况下不安全的协议将被忽略(bug 173010).



 



关联





 



外部链接



The protocol is not associated with any program (Firefox Support)



 



译注



1.因为原文发布于mozillzaine,所以其以firefox为示例。



2.事实上,不是打开名为fred的文件。



3.默认安全设置下的Internet Explorer将不会询问,而Firefox将会询问。



4.如图所示



UrlProtocolFireFoxNetworkProtocol-HandlerExpose-All

[翻译]将应用程序注册为URL协议(Registering an Application to a URL Protocol)

原文链接:Registering an Application to a URL Protocol(http://msdn2.microsoft.com/en-us/library/aa767914.aspx

文章《About Asynchronous Pluggable Protocols》(中译[翻译]关于“异步可插协议”(About Asynchronous Pluggable Protocols(APPs)))描述了如何为一个新的协议开发处理程序(处理器handlers)。在一些案例中,可能会描述如何调用另外一个应用程序来处理自定义协议(custom protocol)。注册已经存在的应用程序为一个URL协议处理器即可。一旦应用程序被成功地启动,我们可以使用命令行参数来重新找回URL来启动它。

  • 注册应用程序来处理自定义协议
  • 启动处理程序
  • 示例
  • 相关主题

注册应用程序来处理自定义协议

你必须添加一个新的key以及相关的value到HKEY_CLASSES_ROOT中,来使应用程序可以处理特殊的URL协议。

新注册的key必须与协议scheme相匹配才可以被添加。例如,增加一个“alert:”协议,被增加到HKEY_CLASSES_ROOT的key必须是alert。在这个新的key之下,默认的字符串value将显示新协议的名字,并且URL协议字符串value将包含协议特有的信息或者空字符串。Keys将同样被添加到DefaultIconshell中。

默认的DefaultIcon key的字符串value必须是新URL协议图标文件名的路径。(译注1:DefaultIcon key

shell key之下,一个key使用一个动词(就像open)将被添加。一个command(命令) key和一个DDEEXEC(动态数据交换执行) key都是使用动词来添加的。这command和DDEEXEC keys之后的values都是用来调用(或者启动)处理新协议的应用程序。

 

启动处理程序

当一个用户点击一个注册了你的自定义URL协议的链接后,Windows Internet Explorer(IE)启动注册的URL协议的处理器。如果指定shellopen命令在注册表中包含一个%1参数的话,Internet Explorer传递这个URI给注册协议的处理器。这最后的统一资源标识符(URI)被编码(%1);即16进制换码符被转换为等价的UTF-16字符。例如,用%20字符串取代空格。

安全警示:应用程序处理URL协议必须全力面对恶意数据。因为处理程序接收来自不信任源的数据,URL和其它参数值传递给应用程序可能包含的恶意数据企图使用处理程序。因此,处理程序可以首先启动基于外部数据的空闲行为确认这些行为以及它们的用户。

注意:另外,处理程序将要有能力处理URLs有可能太长或者包含意想不到(或者多余的)字符串。更多信息,请参看《Writing Secure Code

 

示例

接下来的例子演示如何注册alert.exe应用程序,来处理alert协议。

HKEY_CLASSES_ROOT
alert

(Default) = "URL:Alert Protocol"
URL Protocol = ""
DefaultIcon
(Default) = "alert.exe"
shell
open
command

(Default) = "C:\Program Files\Alert\alert.exe" "%1"


增加这些设置信息到注册表,尝试导航到像“alert:Hello%20World”这样的URLs中,将会尝试启动alert.exe程序并且在命令行中传递“Hello World”


下面的代码包含了一个简单的C#控制台应用程序演示了一种实现alert协议处理程序的方式。



using System;
using System.Collections.Generic;
using System.Text;

namespace Alert1
{
class Program
{
static string ProcessInput(string s)
{
// TODO Verify and validate the input
// string as appropriate for your application.
// return s;
}

static void Main(string[] args)
{
Console.WriteLine("Alert.exe invoked with the following parameters.\r\n");
Console.WriteLine("Raw command-line: \n\t" + Environment.CommandLine);

Console.WriteLine("\n\nArguments:\n");
foreach (string s in args)
{
Console.WriteLine("\t" + ProcessInput(s));
}
Console.WriteLine("\nPress any key to continue...");
Console.ReadKey();
}
}
}


 


相关主题



  • About Asynchronous Pluggable Protocols


  • Debugging Tips

     



    译注



    2.详细步骤:




    1. 编写如上所示的控制台程序,并记录下exe所在的全路径;


    2. 开始->运行->输入“REGEDIT”确定,以启动“注册表编辑器”;


    3. 找到(通常是第一个)HKEY_CLASSES_ROOT节点,右键新建项,输入你期望的协议名,如GoCool;


    4. 同样方式建立如下所示层级结构:

      UrlProtocol


    5. 在浏览器执行:

      UrlProtocolResult



    值得注意的是参数会默认以“,”开始,不过没关系,能够得到所有的URL字符串,对我们来说,其他内容也就是一些老调重弹了。这个“,”就是在设置command中的那个"……","%1"中的这个逗号。也可以用“C:\GoCoolCenter\MyCSharpProject\ConsoleApplication\CA_RegisteringHandlingCustomProtocol\CA_RegisteringHandlingCustomProtocol\bin\Debug\CA_RegisteringHandlingCustomProtocol.exe "%1"”的语句来代替之前的语句。去掉“"%1"”两边的引号,之后的参数将以空格进行分隔输出。


  • [翻译]调试技巧(Debug Tips)

    原文链接:http://msdn2.microsoft.com/en-us/library/aa767915(VS.85).aspx

    文章提供了一些可插协议(pluggable protocols)处理异常和理解生成的HRESULT错误码的技巧。

     

    处理异常

    首先说说Windows Internet Explorer7,Urlmon.dll将安静地处理这些由可插协议引起的异常。开发者在这种配置下需要使用调试工具在异常通过Urlmon.dll的时候试着调试这些自定义处理器。

    IE7所带的Urlmon.dll版本将不再处理异常。开发者必须在可插协议中自行实现一个全局的异常处理程序。

     

    错误代码

    一些函数和方法返回非标准的HRESULT值,就像IInternetSecurityManager::SetZoneMapping。许多这些返回值是由宏生成的,它们设置低位为有效的Microsoft Win32错误码将高位设置为8007。

    [翻译]关于“异步可插协议”(About Asynchronous Pluggable Protocols(APPs))

    原文链接:http://msdn2.microsoft.com/en-us/library/aa767916(VS.85).aspx

    异步可插协议允许开发者创建可插协议处理器,MIME过滤器,以及命名空间处理器工作在微软IE4.0浏览器以及更高版本或者URL moniker中。这篇文章涵盖了Urlmon.dll动态链接库所公开(输出)的可插协议诸多功能。关于Urlmon.dll针对其他APIs所公开(输出)的信息,可以查看URL Monikers和URL Security Zones文章。

    (以下链接指向原文)

  • 益处Benefits
  • 概要Scenarios
  • 先决依赖条件Prerequisites and Dependencies
  • 关于URLs以及NamespacesAbout URLs and Namespaces
  • 关于可插协议About Pluggable Protocols
  • 创建一个异步可插协议处理器Creating an Asynchronous Pluggable Protocol Handler
  • 相关主题Related Topics

     

    益处

    应用程序可以使用可插协议处理器来处理自定义URL协议方案或者为指定的MIME类型过滤数据。

    允许开发者有能力通过使用URL monikers为IE4.0以上版本和应用程序实现新的或者自定义的协议方案处理自定义URL协议方案的可插协议处理方案。(The ability to handle a custom URL protocol scheme using a pluggable protocol handler allows developers to implement new or custom protocol schemes for Internet Explorer 4.0 (and later) and for applications that use URL monikers.)Windows Internet Explorer已存在的协议如HTTP和FTP都包括在默认的协议处理器中。

    可插协议过滤器可以被用来为指定的MIME类型过滤数据。不像标准的协议处理器和可插的命名空间处理器只提供数据,可插协议过滤器不仅提供数据,还要读取数据。可插MIME过滤器通过可插协议处理器通过实现IInternetProtocolSink接口读取下载的数据。在数据被处理完之后,MIME过滤器通过IInternetProtocol接口允许系统重新得到经过处理的数据。

     

    概要

    让我们说说已经介绍的新的协议方案和你的公司想要为IE4.0以上版本用户提供的支持。可插协议允许你在新的协议方案基础上,提供能够被任何请求调用的新的协议处理程序。

    或者说,你的公司想要设计一个能够帮助他们的用户(一些家长)监管他们的孩子在互联网上阅读黄色的信息的产品。你可以设计一个可插的MIME过滤器,将它们注册为监管所有的text/*的MIME类型,并且将所有这些亵渎的东西替换成<BEEP>标签或者一些类似的东西。任何内容都有一个匹配的MIME类型,就像网页(MIME通常为text/html),将调用可插拔的MIME过滤器并将过滤后的数据传给用户。

     

    先决依赖条件

    这个文档假设你明白Microsoft Win32编程。并且你需要明白OLE和组件对象编程(COM)以及URL中的格式化和符号。更多信息可以参看RFC-1738 on Uniform Resource Locators (URL)

    使用Urlmon.dll提供的功能编译程序,确保在你的include目录下包含了Urlmon.h头文件并且Urlmon.lib类库文件在你用的的C/C++编辑器所使用的类库文件夹中。

     

    关于URLs以及Namespaces

    URL跟随的符号描述在RFC1738中,指定了协议方案跟随的指定方案的一部分(<scheme>:<scheme-specific portion>)。例如,在URL http://www.microsoft.com中,“http”是scheme,“//www.microsoft.com”是指定方案的一部分。

    这个指定方案的一部分的起始节(section)包含服务器名。这部分URL通常被引用来作为URL的命名空间。

     

    关于可插协议

    IE使用两种注册新URL协议处理器的机制。第一种方式是注册URL协议并且将它和应用程序相关联并尝试让所有的这种URL都转向指定的URL协议处理器以起到用协议启动程序的作用。(例如,注册用于处理mailto:或者new:的URL协议的应用程序)。第二种方式是使用异步可插协议API,它允许你通过映射协议方案到一个类来定义新的协议。

    关于如何为一个应用程序注册一个指定的URL协议的更多信息,请参看Registering an Application to a URL Protocol。(中译:[翻译]将应用程序注册为URL协议(Registering an Application to a URL Protocol)

    异步可插协议提供三种将协议方案映射到类的方式:

    • 永久地将一个异步可插协议处理器添加到注册表中。这个处理程序处理来自有所有列入清单的方案的任意的URL。(如HTTP,FTP等)。(译注1)
    • 注册临时的可插命名空间处理器。这个处理程序处理来自有所有特殊指定方案的任意的URL。(译注1)
    • 注册一个永久的或者临时的MIME过滤器。处理器将处理它接收的数据流并为任何指定MIME类型的资源返回数据流。

    注意:所有异步可插协议必须支持BINDF_NO_UIBINDF_SILENTOPERATION 标记。

    异步可插协议相关接口

    异步可插协议相关函数

     

    关于异步可插协议

    异步可插协议处理器是一个用于处理任何注册为协议方案的调用的线程单元COM对象。当客户端程序作出请求,Urlmon在注册表中查看协议方案并创建一个已经为这个协议方案注册的协议处理程序的实例。如果协议注册方案被成功地映射到协议处理器的类标识(CLSID),将调用IClassFactory接口的CoCreateInstance方法。协议处理器通过IClassFactory::CreateInstance函数来获得实例。

    注册自定义协议,在注册表中为协议方案添加一个key到HKEY_CLASSES_ROOT\PROTOCOLS\Handler\protocol_scheme下。在这个key名下,添加一个字符串为CLSID,必须设置这个协议处理器的CLSID。

    一个注册自定义协议方案的例子,增加一个名为example的key到注册表HKEY_CLASSES_ROOT\PROTOCOLS\Handler下。在这个新key,HKEY_CLASSES_ROOT\PROTOCOLS\Handler\example,添加字符串,CLSID,必须为这个处理程序指派CLSID。任何URLs使用形如example:的协议方案将被这个CLSID标识关联的协议处理器所处理。

    协议处理器不能使用任何微软Windows消息机制转回到线程中,协议处理器必须工作在非GUI线程中。

    注意:所有的异步可插协议必须支持the BINDF_NO_UI 和BINDF_SILENTOPERATION标记。

     

    关于异步命名空间处理器

    临时可插命名空间处理器用来处理所有用(指定)协议方案的URLs,临时可插命名空间处理器被注册在一个特殊的进程中。你可以通过IInternetSession接口注册或者取消临时可插命名空间处理器。

     

    关于可插MIME过滤器

    可插MIME过滤器是一个接收流的异步可插协议,执行一些数据操作并且返回数据流。输出流可能不同于原始的流。

    更多关于如何在IE4.0中定义MIME类型的信息,请参看MIME Type Detection in Internet Explorer

    注意:所有的异步可插MIME过滤器必须支持BINDF_NO_UI和BINDF_SILENTOPERATION标记。

    另外,之可以通过指定于URL的特定资源通过IE来调用可插的MIME过滤器。MIME将不被其他通过指定URL关联的资源调用(就像HTML页里面的图像)。

     

    永久的可插MIME过滤器

    你必须使用key HKEY_CLASSES_ROOT\PROTOCOLS\Filter\<mime_filter>以及设置了CLSID的value,在注册表中注册一个永久的可插MIME过滤器。

     

    临时可插MIME过滤器

    你可以通过IInternetSession接口注册或者取消一个临时可插MIME过滤器。

     

    创建一个异步可插协议处理器

    按以下步骤来创建一个可插协议处理器:

    1. 实现一个IInternetProtocol接口
    2. 实现一个IInternetProtocolRoot接口
    3. 实现一个IClassFactory接口
    4. 可选。实现一个IInternetProtocolInfo接口。通过事务处理器提供对HTTP协议的支持。
    5. 如果IInternetProtocolInfo已经实现了,为了可以完全地处理安全,为URL安全区域管理提供PARSE_SECURITY_URLPARSE_SECURITY_DOMAIN的支持。
    6. 为你的协议处理器写一些代码。
    7. 提供对BINDF_NO_UI和BINDF_SILENTOPERATION的支持。
    8. 在注册表HKEY_CLASSES_ROOT\PROTOCOLS\Handler下为你的协议处理器增加一个子键。
    9. 在你子键下创建一个字符串value,CLSID,将它设置为你的协议处理器。

    在创建玩协议处理器并将其添加到注册表后,任何程序都可以通过使用由Urlmon.dll提供的功能使用协议处理器。下面的步骤提供当一个拥有你注册的处理器协议方案的URL被调用的时候,Urlmon.dll和你的协议处理器之间的调用的大致的步骤:

    1.Urlmon.dll调用QueryInterface查看你的协议处理器是否实现了IInternetProtocolInfo接口。

    1_Calling the asynchronous pluggable protocol 

    2.如果IInternetProtocolInfo接口已经实现了,Urlmon.dll调用你的可插处理协议的IInternetProtocolInfo::ParseUrl 接口

    2_Calling the asynchronous pluggable protocol 

    当更新了订阅后,IE调用可插协议处理器的IInternetProtocolInfo::QueryInfo方法将QUERYOPTION 值设置为QUERY_USES_CACHE。IE订阅机制将仅支持采用IE缓存机制的可插协议并且让QUERY_USES_CACHE标志为TRUE。

    3.Urlmon.dll调用QueryInterface查看你的可插协议处理器是否支持IInternetProtocol接口

    3_Calling the asynchronous pluggable protocol

    4.Urlmon.dll通过URL调用你的可插协议处理器的IInternetProtocolRoot::Start 方法,并且传递Urlmon.dll的IInternetProtocolSinkIInternetBindInfo接口的地址。

    4_Calling the asynchronous pluggable protocol

    5.你的可插协议处理器将需要接受请求数据。首先将从Internet请求数据。

    5_Requesting the data from Internet

    6.当你的可插协议处理器开始下载数据之后,推荐处理器调用Urlmon.dll的IInternetProtocolSink::ReportData方法。

    6_Notifying the transaction handler that data is available

    7.Urlmon.dll调用你的协议的IInternetProtocol::Read方法。

    7_Reading the data

    8.你的可插协议处理器可以调用Urlmon.dll的IInternetProtocolSink::ReportProgress方法。可插协议处理器必须支持MIME类型,通过使用BINDSTATUS_MIMETYPEAVAILABLE状态码,允许一个可插MIME过滤器被调用(如果有一个为这个MIME类型注册的MIME过滤器的话)。

    8_Reporting process

    9.步骤6到步骤8将一直重复到你的协议处理程序完成请求数据的下载任务之后。

    10.你的可插协议必须调用Urlmon.dll的IInternetProtocolSink::ReportResult方法。

    10_Reporting results

    11.Urlmon.dll调用你的可插协议处理的IInternetProtocol::LockRequest方法。

    11_Locking results

    12.Urlmon.dll调用你可插协议处理程序的IInternetProtocolRoot::Terminate方法。

    12_Teminating the pluggable protocol

    13.Urlmon.dll调用你的可插协议的IInternetProtocol::Read方法知道所有的数据都被重新取回。

    13_Reading the remaining data

    14.Urlmon.dll调用你的可插协议的IInternetProtocol::UnlockRequest方法。

    14_Unlocking the request

    注意:你的可插协议的IInternetProtocol::Read方法将在调用Urlmon.dll之后持续运行,甚至所有的数据已经读取完毕还将继续。所有的一部可插协议处理程序必须做好处理这些可能的准备。

     

    创建一个可插的MIME过滤器

    一个可插的MIME过滤器本质上只是一个实现了IInternetProtocolSink接口的异步可插处理器。Urlmon.dll使用实现了IInternetProtocolSink的可插的MIME过滤器来通知Urlmon.dll数据已经被过滤了。

    另外,过滤器处理多种MIME类型必须为每一种MIME类型注册一个特殊的CLSID单独处理它们。

    1.事务处理器调用可插协MIME过滤器的IInternetProtocolRoot::Start方法。

    MIME_1_Reading the data

    2.事务处理器调用可插协MIME过滤器的InternetProtocolSink::ReportProgressIInternetProtocolSink::ReportData方法。

    MIME_2_Reading the data

    3.可插MIME过滤器调用事务处理器的IInternetProtocol::Read方法。

    MIME_3_Reading the data

    4.可插MIME过滤器调用事务处理器的IInternetProtocolSink::ReportData方法。

    MIME_4_Reading the data

    5.事务处理器调用可插协MIME过滤器的IInternetProtocol::Read方法。

    MIME_5_Reading the data 

    相关主题

     

    译注

    1.异步可插协议处理器可以被指定为在所有进程内有效,而异步可插命名空间协议处理器仅被指定为在某个具体的进程内有效。