原理:程序安装完成之后,修改了注册表,让windows系统知道了这种协议开头的,应该请求哪个程序。
首先我们编写一个RegeditHelper.cs
using System; using System.Text.RegularExpressions; using Microsoft.Win32; public class RegeditHelper { /// <summary> /// 注册协议 /// </summary> /// <param name="Root_Key">根节点</param> /// <param name="file_application_path">应用程序路径</param> /// <param name="file_application_ico">应用程序打开图标,可选值</param> /// <returns></returns> public static bool RegeditAdd(string Root_Key, string file_application_path, string file_application_ico) { //获取注册表HKEY_CLASSES_ROOT RegistryKey reg_ClassRoot = Registry.ClassesRoot; try { RegistryKey reg_key = reg_ClassRoot.OpenSubKey(Root_Key, true); if (reg_key == null) { //创建子节点HKEY_CLASSES_ROOT\tpswftest RegistryKey reg_sjbs = reg_ClassRoot.CreateSubKey(Root_Key); //添加默认项 reg_sjbs.SetValue("", "URL: " + Root_Key + " Protocol Handler"); //协议别名 reg_sjbs.SetValue("URL Protocol", file_application_path); //创建[HKEY_CLASSES_ROOT\tpswftest\DefaultIcon] RegistryKey reg_DefaultIcon = reg_sjbs.CreateSubKey("DefaultIcon"); if (!String.IsNullOrEmpty(file_application_ico)) { //设置自定义图标 reg_DefaultIcon.SetValue("", file_application_ico); } else { //设置系统定义图标 reg_DefaultIcon.SetValue("", file_application_path + ",1"); } //创建呼出处理程序[HKEY_CLASSES_ROOT\tpswftest\shell\open\command] RegistryKey reg_command = reg_sjbs.CreateSubKey("shell").CreateSubKey("open").CreateSubKey("command"); //%1 表示传递的参数,再次%1表示调用处显示链接文本 reg_command.SetValue("", "\"" + file_application_path + "\" \"%1\""); } return true; } catch (Exception ex) { return false; } finally { reg_ClassRoot.Close(); } } /// <summary> /// 删除协议 /// </summary> /// <param name="Root_Key">根节点</param> /// <returns></returns> public static bool RegeditDelete(string Root_Key) { //获取注册表HKEY_CLASSES_ROOT RegistryKey reg_ClassRoot = Registry.ClassesRoot; try { //获取注册表[HKEY_CLASSES_ROOT\tpswftest]项 RegistryKey reg_sjbs = reg_ClassRoot.OpenSubKey(Root_Key, true); if (reg_sjbs != null) { reg_ClassRoot.DeleteSubKeyTree(Root_Key); return true; } else { return false; } } catch (Exception ex) { //添加错误日志 return false; } finally { reg_ClassRoot.Close(); } } /// <summary> /// 处理页面传回的参数的非法字符 /// </summary> /// <param name="sParameterValue">The s parameter value.</param> public static void FilterInvalidCharacter(ref string sParameterValue) { int nStrLength = sParameterValue.Length; if (nStrLength > 0) { if ('/' == sParameterValue[nStrLength - 1]) { if (1 == nStrLength) { sParameterValue = ""; } else { sParameterValue = sParameterValue.Substring(0, nStrLength - 1); } } } } /// <summary> /// Sets the value. /// </summary> /// <param name="args">The arguments.</param> /// <returns></returns> public static void SetValue(string args) { string sParameterValue = Regex.Match(args, "^[0-9a-zA-Z]+://(.+)$").Groups[1].Value; RegeditHelper.FilterInvalidCharacter(ref sParameterValue); Registry.SetValue(@"HKEY_CURRENT_USER\Software\OraAnsParameters", "", sParameterValue); //将经过处理的传入参数写入注册表 } /// <summary> /// Gets the value. /// </summary> /// <returns></returns> public static string getValue() { string val = ""; object Obj = Registry.GetValue(@"HKEY_CURRENT_USER\Software\OraAnsParameters", "", string.Empty); if (Obj != null) { val = Obj as string; Registry.SetValue(@"HKEY_CURRENT_USER\Software\OraAnsParameters", "", string.Empty); } return val; } }
修改我们的程序Program.cs,这里顺便让他以管理员方式启动,这样我们程序才有修改注册表的权限
static class Program { /// <summary> /// 应用程序的主入口点。 /// </summary> /// <param name="args">The arguments.</param> [STAThread] static void Main(string[] args) { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); //取值 暂存注册表 if (args.Length > 0) //从页面启动时有参数传入,否则直接启动 { RegeditHelper.SetValue(args[0]); } //获得当前登录的Windows用户标示 System.Security.Principal.WindowsIdentity identity = System.Security.Principal.WindowsIdentity.GetCurrent(); System.Security.Principal.WindowsPrincipal principal = new System.Security.Principal.WindowsPrincipal(identity); if (principal.IsInRole(System.Security.Principal.WindowsBuiltInRole.Administrator)) { //如果是管理员,则直接运行 Application.Run(new FrmMain(args)); } else { //创建启动对象 System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo(); startInfo.UseShellExecute = true; startInfo.WorkingDirectory = Environment.CurrentDirectory; startInfo.FileName = Application.ExecutablePath; //设置启动动作,确保以管理员身份运行 startInfo.Verb = "runas"; try { System.Diagnostics.Process.Start(startInfo); } catch { return; } //退出 Application.Exit(); } } }
我们可以在安装程序完成之后或者第一次打开窗体加载事件中,执行一次操作注册表
private void FrmMain_Load(object sender, EventArgs e) { string apppath = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;//获取程序目录 bool result = RegeditHelper.RegeditAdd("carsonyang", apppath, "");//这里就是创建协议 }
然后就是在你的窗体初始化事件或者加载事件中获取数据了。
var par = RegeditHelper.getValue();
可以写个html页面测试一下
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta charset="utf-8" /> <title></title> </head> <body> <div> <a href="carsonyang://par1"> 打开1 </a> <br> <a href="carsonyang://par2"> 打开2 </a> <br> <a href="carsonyang://par3"> 打开3 </a> <br> <a href="carsonyang://par4"> 打开4 </a> <br> </div> </body> </html>
这个四个链接打开,程序会得到href的完整字符串,我们再通过处理,最终得到双斜杠后面的参数
留下您的脚步
最近评论