zoukankan      html  css  js  c++  java
  • 利用Register protocol实现网页调用桌面程序(类似迅雷、QQ等)

    前言

    我们经常看到 tencent://.. thunder://     这两种开头的网址,往往觉得很奇怪,很想弄懂其中的原理,是如何实现的,我查找了相关的 资料,终于找到了,跟大家分享下。

    原理篇

    微软官方说明:http://msdn.microsoft.com/en-us/library/Aa767914.aspx

    tencent://.. thunder://      是 腾讯 和 迅雷 的协议,即页面上或地址栏里的链接只要输入带有 tencent://… 的协议,就会自动调用一个已写好的程序执行该协议的操作。 或者是打开页面,迅雷的是下载资源的链接     。
    通过微软的说明,知道这是Register protocol,对于 Windows、Linux 和 OS X 操作系统都可以注册这样的协议。
    比如说 Windows,其实只需写入注册表,即可实现协议与执行程序的关联。
    例如腾讯的协议注册表如下:
    [HKEY_CLASSES_ROOTTENCENT]
    @=”TencentProtocol”
    “URL Protocol”=”D:\Program Files\Tencent\QQ\Timwp.exe”
    [HKEY_CLASSES_ROOTTENCENTDefaultIcon]
    @=”D:\Program Files\Tencent\QQ\Timwp.exe,1″
    [HKEY_CLASSES_ROOTTENCENTshell]
    [HKEY_CLASSES_ROOTTENCENTshellopen]
    [HKEY_CLASSES_ROOTTENCENTshellopencommand]
    @=””D:\Program Files\Tencent\QQ\Timwp.exe” ”%1”"

    所实现的就是当浏览器(或其它)碰到 tencent://… 时,自动调用 Timwp.exe,并把 tencent://… 地址作为第一个参数传递给 Timwp.exe。

    实现篇

    下面我们自己来实现这样的需求:

    要实现如上功能,最主要的还是对注册表的处理。新建一个注册表文件 

    Windows Registry Editor Version 5.00
    
    [HKEY_CLASSES_ROOT/FinstoneRpt]
    @="FRptProtocol"
    "URL Protocol"="I://Release//CZBYReport.exe"
     
    [HKEY_CLASSES_ROOT/FinstoneRpt/DefaultIcon]
    @="I://Release//CZBYReport.exe,0"
     
    [HKEY_CLASSES_ROOT/FinstoneRpt/shell]
     
    [HKEY_CLASSES_ROOT/FinstoneRpt/shell/open]
     
    [HKEY_CLASSES_ROOT/FinstoneRpt/shell/open/command]
    @="/"I://Release//CZBYReport.exe/" /"%1/""

    以上定义了协议名:FinstoneRpt,及相关调用处理程序的位置。各位可自行调整。
    将上述内容导入到注册表中,然后在相关网页里加上一个连接:

    01.<a href="FinstoneRpt://message/?id=3e5065a6-19a0-41e6-afab-db7cc4bd3c76">test</a> 

    当点击时,则会调用注册表中记录的程序。当然该程序可以接受参数:就是href里的所有内容。可根据情况自行判断处理。 


    如需通过VS的安装程序实现安装时自动执行以上操作。在安装程序里,导入上述注册表文件,因为用户安装时的路径不一样,要定位注册表中记录的程序,只需在VS里将相关注册键值修改:



    将涉及具体地址都一一改成[TARGETDIR]程序名,即可。

    当你注册协议后,你就可以用指定的程序去“解释”这个协议,在软件里通过取命令行(Environment.CommandLine)获取传递过来的参数就行了.

    写注册表示例代码

    public void WriteRegistry(string protocolName, string applicationPath)
            {
                string regData = string.Empty;
                RegistryKey regkey = Registry.ClassesRoot;
                if (regkey.GetSubKeyNames().Where(t => t == protocolName).Count() > 0) { regkey.DeleteSubKeyTree(protocolName); };
                RegistryKey xiaozijie = regkey.CreateSubKey(protocolName);
                xiaozijie.SetValue("", protocolName+"Protocol");
                xiaozijie.SetValue("URL Protocol", applicationPath);
                RegistryKey defaultIcon = xiaozijie.CreateSubKey("DefaultIcon");
                defaultIcon.SetValue("", applicationPath);
                var shell = xiaozijie.CreateSubKey("shell");
                var open = shell.CreateSubKey("open");
                var command = open.CreateSubKey("command");
                command.SetValue("", string.Format(""{0}" "{1}"",applicationPath,"%1"));
            }

    需要用管理员身份运行

    取得参数代码:

    Environment.CommandLine;

  • 相关阅读:
    Spring 循环依赖的三种方式(三级缓存解决Set循环依赖问题)
    终于有人把“TCC分布式事务”实现原理讲明白了
    Java synchronized 关键字的实现原理
    Synchronized的实现原理(汇总)
    Spring的Bean的生命周期(大众版)
    Synchronized与Lock的区别与应用场景
    Lock与synchronized 的区别
    线程的同步控制synchronized和lock的对比和区别
    lock和synchronized的同步区别与选择
    Mybatis3.x与Spring4.x整合
  • 原文地址:https://www.cnblogs.com/xdoudou/p/3945200.html
Copyright © 2011-2022 走看看