zoukankan      html  css  js  c++  java
  • 页面----调用本地程序

    web页面调用本地程序

    起因:

     最近由于项目需要在web页面中调用本地部署的exe程序;进而对该功能实现做了对应了解;以及存在的问题进行记录。

     要实现该功能就不得不说浏览器自定义协议;解决办法:那么它是什么呢?

    浏览器自定义协议:

      浏览器自定义协议,其实是微软提供 Asynchronous Pluggable Protocols可以用来注册本地应用程序到 URI Scheme

       https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/platform-apis/aa767914(v=vs.85)

     实现自定义协议方式—添加注册表:

    复制代码
    Windows Registry Editor Version 5.00
    
    [HKEY_CLASSES_ROOT协议名称]
    @="程序运行地址"
    "URL Protocol"=""
    
    [HKEY_CLASSES_ROOTcalldemoDefaultIcon]
    @="程序运行地址,1"
    
    [HKEY_CLASSES_ROOTcalldemoshell]
    
    [HKEY_CLASSES_ROOTcalldemoshellopen]
    
    [HKEY_CLASSES_ROOTcalldemoshellopencommand]
    @="程序地址" "%1""
    复制代码

    自定义协议实现示例:  

     示例实现:实现一个本地Exe,并注册到注册表中;并运行效果。(程序比较简单,可以查看github) 

     程序实现写入注册表主要逻辑: 

    复制代码
    static class Program
    {
    /// <summary>
    /// 应用程序的主入口点。
    /// </summary>
    [STAThread]
    static void Main(string[] args)
    {
        RegisterUrlProtocol();
    
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        var from = new Form1();
        //显示输入参数
        from.Args = args;
        Application.Run(from);
    }
    /// <summary> /// 注册自定义协议 /// </summary> private static void RegisterUrlProtocol() { try { //检查是否注册自定义协议:如未注册则注册 Register register = new Register("calldemo", RegDomain.ClassesRoot); if (!register.IsSubKeyExist("calldemo")) { //注册: register.CreateSubKey(); register.WriteRegeditKey("", $"{Application.ExecutablePath}"); register.WriteRegeditKey("URL Protocol", ""); if (!register.IsSubKeyExist(@"calldemoDefaultIcon")) { register.CreateSubKey(@"calldemoDefaultIcon"); register.SubKey = @"calldemoDefaultIcon"; register.WriteRegeditKey("", $"{Application.ExecutablePath},1"); } if (!register.IsSubKeyExist(@"calldemoshell")) { register.CreateSubKey(@"calldemoshell"); register.CreateSubKey(@"calldemoshellopen"); register.CreateSubKey(@"calldemoshellopencommand"); register.SubKey = @"calldemoshellopencommand"; //添加默认键 register.WriteRegeditKey("", $""{Application.ExecutablePath}" "%1""); } } } catch (Exception e) { MessageBox.Show(e.Message); throw; } } 
    复制代码

     创建检验html:  

     <a href="calldemo:123qwe">UrlProtocolDemo</a>

     运行效果:

      

     github地址:https://github.com/cwsheng/URLProtocolDemo.git

    问题记录:

     1、关于js中检验浏览器自定义协议是否存在,现在没有教好的解决办法?

      开源项目:https://github.com/ismailhabib/custom-protocol-detection(亲测无效,且不维护了)

           https://github.com/Veryfirefly/custom-protocol-detection(原理同上,也无效)

      问题:https://stackoverflow.com/questions/836777/how-to-detect-browsers-protocol-handlers

     2、每次调用启动exe,都会新运行一个程序实例;可以通过程序实现判断该程序是否已经在运行。

    复制代码
    #region 确保程序只运行一个实例
    private static Process RunningInstance()
    {
        Process current = Process.GetCurrentProcess();
        Process[] processes = Process.GetProcessesByName(current.ProcessName);
        //遍历与当前进程名称相同的进程列表 
        foreach (Process process in processes)
        {
            //如果实例已经存在则忽略当前进程 
            if (process.Id != current.Id)
            {
                //保证要打开的进程同已经存在的进程来自同一文件路径
                if (Assembly.GetExecutingAssembly().Location.Replace("/", "\") == current.MainModule.FileName)
                {
                    //返回已经存在的进程
                    return process;
                }
            }
        }
        return null;
    }
    //3.已经有了就把它激活,并将其窗口放置最前端
    private static void HandleRunningInstance(Process instance)
    {
        ShowWindowAsync(instance.MainWindowHandle, 1); //调用api函数,正常显示窗口
        SetForegroundWindow(instance.MainWindowHandle); //将窗口放置最前端
    }
    [DllImport("User32.dll")]
    private static extern bool ShowWindowAsync(System.IntPtr hWnd, int cmdShow);
    [DllImport("User32.dll")]
    private static extern bool SetForegroundWindow(System.IntPtr hWnd);
    #endregion
    复制代码

    最后:

     当然该方式不一定是唯一实现方式,也可以尝试使用WebAssembly实现本地运行程序逻辑,本次未进行验证

     如果js判断自定义协议是否存在,有好到方法也希望能得到大家的解答。

  • 相关阅读:
    085 Maximal Rectangle 最大矩形
    084 Largest Rectangle in Histogram 柱状图中最大的矩形
    083 Remove Duplicates from Sorted List 有序链表中删除重复的结点
    082 Remove Duplicates from Sorted List II 有序的链表删除重复的结点 II
    081 Search in Rotated Sorted Array II 搜索旋转排序数组 ||
    080 Remove Duplicates from Sorted Array II 从排序阵列中删除重复 II
    079 Word Search 单词搜索
    078 Subsets 子集
    bzoj2326: [HNOI2011]数学作业
    bzoj2152: 聪聪可可
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/14086356.html
Copyright © 2011-2022 走看看