自定义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.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
然后我在浏览器中点这个链接 ,啥效果?你猜
哇咔咔 真的调用了我的test.exe,并且显示了hello !
也可以在运行窗口输入:xishui://hello 调用
二,写代码实现
#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 }