技术思绪摘录旅行笔记
我们经常会看到网页拉起QQ、拉起迅雷,我们能不能写一个自己程序,让网页也能拉起我们自己的程序呢?这篇文章就介绍了如何操作才能拉起我们的自己的程序。

原理:程序安装完成之后,修改了注册表,让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的完整字符串,我们再通过处理,最终得到双斜杠后面的参数


CarsonIT 微信扫码关注公众号 策略、创意、技术

留下您的脚步

 

最近评论

查看更多>>

站点统计

总文章数:275 总分类数:18 总评论数:88 总浏览数:124.81万

精选推荐

阅读排行

友情打赏

请打开您的微信,扫一扫