起因:

 最近由于项目需要在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_ROOT\calldemo\DefaultIcon]
@="程序运行地址,1" [HKEY_CLASSES_ROOT\calldemo\shell] [HKEY_CLASSES_ROOT\calldemo\shell\open] [HKEY_CLASSES_ROOT\calldemo\shell\open\command]
@="程序地址" \"%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(@"calldemo\DefaultIcon"))
{
register.CreateSubKey(@"calldemo\DefaultIcon");
register.SubKey = @"calldemo\DefaultIcon";
register.WriteRegeditKey("", $"{Application.ExecutablePath},1");
}
if (!register.IsSubKeyExist(@"calldemo\shell"))
{
register.CreateSubKey(@"calldemo\shell");
register.CreateSubKey(@"calldemo\shell\open");
register.CreateSubKey(@"calldemo\shell\open\command");
register.SubKey = @"calldemo\shell\open\command";
//添加默认键
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判断自定义协议是否存在,有好到方法也希望能得到大家的解答。

【问题记录】— web页面调用本地程序的更多相关文章

  1. 从web页面启动winform程序的实现方法

    本文实现的需求是: A.通过web页面启动winform程序: B.将页面的参数传递给winform程序: C.winform程序已经启动并正在运行时,从web页面不能重新启动winform程序,只是 ...

  2. 通过私有协议Chrome浏览器页面打开本地程序

    近期方有这样的要求:这两个系统,根据一组Chrome开展,根据一组IE开展,需要Chrome添加一个链接,然后进入IE该系统的开发.这,需要Chrome跳转到创建一个链接IE浏览器指定的页面.同时也实 ...

  3. 细说Web页面与本地电脑通讯

    话说在很久很久以前.Web页面与客户的本地电脑Localhost通讯,有两种方式: 1.Flash 2.ActiveX控件 由于Flash本人不是很了解,也给出不了什么示例代码, 对于ActiveX控 ...

  4. 网页调用本地程序(Windows下浏览器全兼容)

    用网页调用本地应用程序的思路是,先进行注册表注册自定义一个URL Protocol协议,再利用URL Protocol实现网页调用本地应用程序. 1.先写一个注册表文件,将其保存为.reg后缀的注册表 ...

  5. web页面调用支付宝支付

    web页面调用支付宝支付 此文章是前端单独模拟完成支付,若在线上环境则需要后台配合产生签名等参数 在蚂蚁金服开放平台申请沙箱环境 将沙箱环境中的密钥.应用网关.回调地址补全,生成密钥的方法在此 配置好 ...

  6. [转]从网页Web上调用本地应用程序(.jar、.exe)的主流处理方法

    这个方法主要思路是利用自定义URL Protocol来调用应用程序.浏览器在解析到自定义URL Protocol之后,会寻找注册表,然后通过注册表启动相应的程序,然后启动改程序,传入参数.对于我这个项 ...

  7. web页面和小程序页面实现瀑布流效果

    小程序实现瀑布流效果,和web页面差不多,都要经过以下步骤: 1).加载图片,获取图片的宽高度: 2).根据页面需要显示几列计算每列的宽度: 3).根据图片真实宽度和每列的宽度比,计算出图片需要显示的 ...

  8. js调用本地程序

    前几天,做项目时候用到js调用本地的程序,找了好多资料,一种是写入注册表,一种是写一个浏览器插件,相对来说,写一个注册表更简单一点,因为需求很紧.下面就是我的总结,希望可以对你们有所帮助,具体从哪里找 ...

  9. 自定义浏览器协议,实现web程序调用本地程序

    转自  http://blog.csdn.net/talking12391239/article/details/40712759 亲测可用 tencent://Message/?Uin=000000 ...

随机推荐

  1. Excel基础—为什么学习Excel

    吾生也有涯,而知也无涯 点赞再看,养成习惯 自从个人计算机开始普及以后,Excel就得到了广泛的传播,工作学习生活中不处不存在Excel的影子,不论是考勤,工资还是其他的统计等等,都离不开Excel. ...

  2. Luogu P5087 数学

    题意 给定一个长度为 \(n\) 的序列 \(a_i\),求出在这个序列中所有选出 \(k\) 个元素方案中元素的乘积之和. \(\texttt{Data Range:}1\leq n\leq 10^ ...

  3. 4G DTU的通信距离是多少

    4G是现今应用非常广泛的一种通信技术,主要是为广义的远程信息处理提供服务.随着计算机与各种具有处理功能的智能设备在各领域的日益广泛使用,数据通信的应用范围也日益扩大.在物联网领域中,4G是移动设备实现 ...

  4. net core webapi多版本控制与nswag 交互

    前言 首先希望webapi 支持多版本,swagger针对不同的版本可进行交互.netcore 基于Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer 包, ...

  5. python之冒泡排序改进

    冒泡排序改进 关注公众号"轻松学编程"了解更多. 一.普通冒泡排序 [22,3,1,6,7,8,2,5] 普通冒泡排序 思路: 第一趟排序 从下标0开始,取出对应的值22 22和3 ...

  6. 834. Sum of Distances in Tree —— weekly contest 84

    Sum of Distances in Tree An undirected, connected tree with N nodes labelled 0...N-1 and N-1 edges a ...

  7. Dapr Java Http 调用

    版本介绍 Java 版本:8 Dapr Java SKD 版本:0.9.2 Dapr Java-SDK HTTP 调用文档 有个先决条件,内容如下: Dapr and Dapr CLI. Java J ...

  8. CSS ------ 样式学习 (一)

    CSS 指层叠样式表 (Cascading Style Sheets) :定义如何显示 HTML 元素(一套自定义的衣服) 语法: 由选择器和声明(可以是一条或多条)构成, 声明以大括号({})括起来 ...

  9. C# 字符串处理类

    using System;using System.Collections.Generic;using System.Text;using System.Text.RegularExpressions ...

  10. leetcode144add-two-numbers

    题目描述 给定两个代表非负数的链表,数字在链表中是反向存储的(链表头结点处的数字是个位数,第二个结点上的数字是十位数...),求这个两个数的和,结果也用链表表示. 输入:(2 -> 4 -> ...