起因:

 最近由于项目需要在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. sqlsugar入门(3)-DateTime.ToString("yyyy-MM-dd HH:mm:ss.fff")源码修改

    1.注释SqlSugar\ExpressionsToSql\ResolveItems\MethodCallExpressionResolve文件下的GetMethodValue方法 case &quo ...

  2. nb-iot模块实现联网的威力体现

    窄带物联网(nb-iot)是一种越来越流行的方法,用于创建具有持久电池寿命,快速和功能丰富的互连设备系统.自2016年创建nb-iot以来,nb-iot设备和nb-iot模块中使用的技术得到了迅速发展 ...

  3. day80:luffy:短信sdk接入&点击获取验证码&注册功能的实现&Celery实现短信发送功能

    目录 1.短信sdk接入 2.前端点击获取验证码效果 3.注册后端接口实现 4.注册-前端 5.Celery 6.Celery完成短信发送功能 1.短信sdk接入 1.准备工作 1.下载云通讯相关的文 ...

  4. soloPi安装使用

    SoloPi脚本转化器正式发布,支持转化为 Appium 与 Macaca 脚本:https://github.com/soloPi/SoloPi-Convertor,脚本转化器使用教程: https ...

  5. Nginx是什么?有什么用?

    一.Nginx是什么 Nginx ("engine x") 是一个高性能的 HTTP 和反向代理服务器,特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服 ...

  6. Linux__用户用户组和权限

    用户用户组和权限 useradd +用户名, 添加这个用户 userdel +用户名, 删除这个用户(有残留 ) userdel -r +用户名, 彻底删除这个用户 groupadd +组名 ,添加这 ...

  7. 转载-git的安装和使用

    首先是安装和配置,参考了以下博客的内容https://www.cnblogs.com/minRose/p/10286473.html 一.下载地址 https://git-scm.com/downlo ...

  8. Codeforce算法题 | 你能想出解法,让你的基友少氪金吗?

    在TechFlow学长的公众号里发现一道挺有意思的CF算法题,现在利用学长的思路学习一下 题目链接:https://codeforces.com/contest/1418/problem/C 题意 这 ...

  9. python代码实现抢票助手

    一. 代码使用Python+Splinter开发,Splinter是一个使用Python开发的开源Web应用测试工具,它可以帮你实现自动浏览站点和与其进行交互. 二. 安装好Python 3或2都可以 ...

  10. 知识全聚集 .Net Core 技术突破 | 简单说说工作单元

    知识全聚集 .Net Core 技术突破 | 简单说说工作单元 教程 01 | 模块化方案一 02 | 模块化方案二 其他教程预览 分库分表项目实战教程 Git地址: https://github.c ...