自定义URL Protocol Handler 呼出应用程序

 

缘起: 迅雷,电驴等软件可以在浏览器中点击一个url后自动启动,并执行操作。这是咋实现的呢?俺google了许多 ,还是在园子里找到了一个文 http://www.cnblogs.com/hwade/archive/2008/01/08/1029686.html ,这个哥哥喜欢写繁体字,虽然俺学过书法,认识一些繁体字,但看着还是不爽。
哎!资质愚钝啊,看了半天没看太明白,但思路是明白了 ,就是要在注册表上动手脚。 于是乎继续google 找到了 http://blogs.gotdotnet.com/noahc/archive/2006/10/19/register-a-custom-url-protocol-handler.aspx 不幸让我看明白了。
俺简单的说说俺的理解吧。
一,手动设置注册表实现


要实现这个功能一共分3步。(我们注册一个xishui:// 这样的 protocol-handler,实现在网页中点击xishui://hello,就弹出一个对话框,上面显示“hello”)
1 按照如下结构建立注册表

其中 [xishui] 是建立在注册表的 [HKEY_CLASSES_ROOT] 主键下。
2 给相关的键赋值






大家注意到上面 command 项的值为 c:\test.exe "%1" ,这个"%1"是传递给test.exe的参数。如果我们点击xishui://hello这样的链接 那么%1的值就是“xishui://hello” 这个字符串。

到此我们改写程序生成test.exe了,我们的目标是弹出一个对话框,显示xishui://hello链接中的hello字样。 也就是说我们要用正则表达式来取出"xishui://hello" 中 “xishui://” 后面的部分

我们来写一个控制台程序

using System;
using System.IO;
using System.Windows.Forms;
using System.Text.RegularExpressions;

namespace test
{
    
class Program
    
{
        
static void Main(string[] args)
        
{
            
string key = Regex.Match(args[0], @"(?<=://).+?(?=:|/|\Z)").Value;
            MessageBox.Show(key);
        }

    }

}


让我把编译生成的test.exe 复制到c:\下
然后 我写了个test.html

<href="xishui://hello">xishui://hello</a>


然后我在浏览器中点这个链接 ,啥效果?你猜



哇咔咔 真的调用了我的test.exe,并且显示了hello !

 

也可以在运行窗口输入:xishui://hello 调用

 

二,写代码实现

 

View Code
  #region main functions

        /// <summary>
        /// 注册协议
        /// </summary>
        /// <param name="Root_Key">根节点</param>
        /// <param name="file_application_path">应用程序路径</param>
        /// <param name="file_application_ico">应用程序打开图标,可选值</param>
        /// <returns></returns>
        public bool RegeditAdd(string Root_Key, string file_application_path, string file_application_ico)
        {
            RegistryKey reg_CurrentUser = Registry.CurrentUser;
            try
            {
                //获取注册表CurrentUser/SOFTWARE/Classes项
                RegistryKey reg_Classes = reg_CurrentUser.OpenSubKey("SOFTWARE", true).OpenSubKey("Classes", true);
                RegistryKey reg_key = reg_Classes.OpenSubKey(Root_Key, true);
                if (reg_key == null)
                {
                    RegistryKey reg_sjbs = reg_Classes.CreateSubKey(Root_Key);
                    //添加默认项
                    reg_sjbs.SetValue("", "URL: " + Root_Key + " Protocol Handler");
                    //协议别名
                    reg_sjbs.SetValue("URL Protocol", file_application_path);
                    RegistryKey reg_DefaultIcon = reg_sjbs.CreateSubKey("DefaultIcon");
                    if (!String.IsNullOrEmpty(file_application_ico) || file_application_ico == "")
                    {
                        //设置自定义图标
                        reg_DefaultIcon.SetValue("", file_application_ico);
                    }
                    else
                    {
                        //设置系统定义图标
                        reg_DefaultIcon.SetValue("", file_application_path + ",1");
                    }
                    //呼出处理程序
                    RegistryKey reg_command = reg_sjbs.CreateSubKey("shell").CreateSubKey("open").CreateSubKey("command");
                    //%1 表示传递的参数,再次%1表示调用处显示链接文本
                    reg_command.SetValue("", "\"" + file_application_path + "\" \"%1\"");
                }
                return true;
            }
            catch { return false; }
            finally { reg_CurrentUser.Close(); }
        }

        /// <summary>
        /// 删除协议
        /// </summary>
        /// <param name="Root_Key">根节点</param>
        /// <returns></returns>
        public bool RegeditDelete(string Root_Key)
        {
            RegistryKey reg_CurrentUser = Registry.CurrentUser;
            try
            {
                //获取注册表CurrentUser/SOFTWARE/Classes项
                RegistryKey reg_Classes = reg_CurrentUser.OpenSubKey("SOFTWARE", true).OpenSubKey("Classes", true);
                RegistryKey reg_sjbs = reg_Classes.OpenSubKey(Root_Key, true);
                if (reg_sjbs != null)
                {
                    reg_Classes.DeleteSubKeyTree(Root_Key);
                    return true;
                }
                return false;
            }
            catch { return false; }
            finally { reg_CurrentUser.Close(); }
        }
        #endregion

        #region control events

        /// <summary>
        /// 协议注册
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_add_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.tabControl1.SelectedIndex == 0)
                {
                    if (this.txt_protocolName.TextLength <= 0)
                    {
                        throw new Exception("请填写协议名称!");
                    }
                    if (this.txt_application.TextLength <= 0)
                    {
                        throw new Exception("请选择需注册的应用程序,如:.exe 文件");
                    }
                }

                if (!RegeditAdd(this.txt_protocolName.Text.Trim(), this.txt_application.Text.Trim(), this.txt_ico.Text.Trim()))
                    throw new Exception("协议注册失败!");
                else { throw new Exception("协议注册成功!"); }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return;
            }
        }

        /// <summary>
        /// 选择处理程序
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_browser_Click(object sender, EventArgs e)
        {
            this.openFileDialog1.FileName = "";
            this.openFileDialog1.Filter = "EXE Files (*.exe)|*.exe|All Files (*.*)|*.*";
            this.openFileDialog1.ShowDialog();
            this.txt_application.Text = this.openFileDialog1.FileName;
        }

        /// <summary>
        /// 双击浏览 选择处理程序
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void txt_application_DoubleClick(object sender, EventArgs e)
        {
            this.openFileDialog1.FileName = "";
            this.openFileDialog1.Filter = "EXE Files (*.exe)|*.exe|All Files (*.*)|*.*";
            this.openFileDialog1.ShowDialog();
            this.txt_application.Text = this.openFileDialog1.FileName;
        }

        /// <summary>
        /// 选择处理程序ico
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_browser1_Click(object sender, EventArgs e)
        {
            this.openFileDialog2.FileName = "";
            this.openFileDialog2.Filter = "ICO Files (*.ico)|*.ico|All Files (*.*)|*.*";
            this.openFileDialog2.ShowDialog();
            this.txt_ico.Text = this.openFileDialog2.FileName;
        }

        /// <summary>
        /// 双击浏览 选择处理程序ico
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void txt_ico_DoubleClick(object sender, EventArgs e)
        {
            this.openFileDialog2.FileName = "";
            this.openFileDialog2.Filter = "ICO Files (*.ico)|*.ico|All Files (*.*)|*.*";
            this.openFileDialog2.ShowDialog();
            this.txt_ico.Text = this.openFileDialog2.FileName;
        }

        /// <summary>
        /// 删除协议
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_delete_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.tabControl1.SelectedIndex == 1)
                {
                    if (this.txt_protocolName1.TextLength <= 0)
                    {
                        throw new Exception("请慎重填写协议名称,以免误删除注册表信息!");
                    }
                }

                if (!RegeditDelete(this.txt_protocolName1.Text.Trim()))
                    throw new Exception("协议卸载失败,由于您输入的协议名称不存在导致卸载失败!");
                else { throw new Exception("协议卸载成功!"); }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return;
            }
        }

        private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (this.tabControl1.SelectedIndex == 0)
            {
                this.richtxt_protocolInsert.Text = "注意:您好!注册协议名称请不要使用注册表已经存在的键,以免误操作影响系统正常功能!在运行中输入【协议名称://】即可调用或者使用web开发超链接中调用!";
            }
            if (this.tabControl1.SelectedIndex == 1)
            {
                this.richtxt_protocolDelete.Text = "注意:您好!卸载协议的时候请检查协议名称是否为自己创建的协议,以免误操作影响系统正常功能!";
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            this.richtxt_protocolInsert.Text = "注意:您好!注册协议名称请不要使用注册表已经存在的键,以免误操作影响系统正常功能!在运行中输入【协议名称://】即可调用或者使用web开发超链接中调用!";
        }

        #endregion
    }

 

 

 

posted @ 2012-12-11 17:17  初雪之恋  阅读(11168)  评论(0编辑  收藏  举报