【问题记录】— 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_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页面调用本地程序的更多相关文章
- 从web页面启动winform程序的实现方法
本文实现的需求是: A.通过web页面启动winform程序: B.将页面的参数传递给winform程序: C.winform程序已经启动并正在运行时,从web页面不能重新启动winform程序,只是 ...
- 通过私有协议Chrome浏览器页面打开本地程序
近期方有这样的要求:这两个系统,根据一组Chrome开展,根据一组IE开展,需要Chrome添加一个链接,然后进入IE该系统的开发.这,需要Chrome跳转到创建一个链接IE浏览器指定的页面.同时也实 ...
- 细说Web页面与本地电脑通讯
话说在很久很久以前.Web页面与客户的本地电脑Localhost通讯,有两种方式: 1.Flash 2.ActiveX控件 由于Flash本人不是很了解,也给出不了什么示例代码, 对于ActiveX控 ...
- 网页调用本地程序(Windows下浏览器全兼容)
用网页调用本地应用程序的思路是,先进行注册表注册自定义一个URL Protocol协议,再利用URL Protocol实现网页调用本地应用程序. 1.先写一个注册表文件,将其保存为.reg后缀的注册表 ...
- web页面调用支付宝支付
web页面调用支付宝支付 此文章是前端单独模拟完成支付,若在线上环境则需要后台配合产生签名等参数 在蚂蚁金服开放平台申请沙箱环境 将沙箱环境中的密钥.应用网关.回调地址补全,生成密钥的方法在此 配置好 ...
- [转]从网页Web上调用本地应用程序(.jar、.exe)的主流处理方法
这个方法主要思路是利用自定义URL Protocol来调用应用程序.浏览器在解析到自定义URL Protocol之后,会寻找注册表,然后通过注册表启动相应的程序,然后启动改程序,传入参数.对于我这个项 ...
- web页面和小程序页面实现瀑布流效果
小程序实现瀑布流效果,和web页面差不多,都要经过以下步骤: 1).加载图片,获取图片的宽高度: 2).根据页面需要显示几列计算每列的宽度: 3).根据图片真实宽度和每列的宽度比,计算出图片需要显示的 ...
- js调用本地程序
前几天,做项目时候用到js调用本地的程序,找了好多资料,一种是写入注册表,一种是写一个浏览器插件,相对来说,写一个注册表更简单一点,因为需求很紧.下面就是我的总结,希望可以对你们有所帮助,具体从哪里找 ...
- 自定义浏览器协议,实现web程序调用本地程序
转自 http://blog.csdn.net/talking12391239/article/details/40712759 亲测可用 tencent://Message/?Uin=000000 ...
随机推荐
- sqlsugar入门(3)-DateTime.ToString("yyyy-MM-dd HH:mm:ss.fff")源码修改
1.注释SqlSugar\ExpressionsToSql\ResolveItems\MethodCallExpressionResolve文件下的GetMethodValue方法 case &quo ...
- nb-iot模块实现联网的威力体现
窄带物联网(nb-iot)是一种越来越流行的方法,用于创建具有持久电池寿命,快速和功能丰富的互连设备系统.自2016年创建nb-iot以来,nb-iot设备和nb-iot模块中使用的技术得到了迅速发展 ...
- day80:luffy:短信sdk接入&点击获取验证码&注册功能的实现&Celery实现短信发送功能
目录 1.短信sdk接入 2.前端点击获取验证码效果 3.注册后端接口实现 4.注册-前端 5.Celery 6.Celery完成短信发送功能 1.短信sdk接入 1.准备工作 1.下载云通讯相关的文 ...
- soloPi安装使用
SoloPi脚本转化器正式发布,支持转化为 Appium 与 Macaca 脚本:https://github.com/soloPi/SoloPi-Convertor,脚本转化器使用教程: https ...
- Nginx是什么?有什么用?
一.Nginx是什么 Nginx ("engine x") 是一个高性能的 HTTP 和反向代理服务器,特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服 ...
- Linux__用户用户组和权限
用户用户组和权限 useradd +用户名, 添加这个用户 userdel +用户名, 删除这个用户(有残留 ) userdel -r +用户名, 彻底删除这个用户 groupadd +组名 ,添加这 ...
- 转载-git的安装和使用
首先是安装和配置,参考了以下博客的内容https://www.cnblogs.com/minRose/p/10286473.html 一.下载地址 https://git-scm.com/downlo ...
- Codeforce算法题 | 你能想出解法,让你的基友少氪金吗?
在TechFlow学长的公众号里发现一道挺有意思的CF算法题,现在利用学长的思路学习一下 题目链接:https://codeforces.com/contest/1418/problem/C 题意 这 ...
- python代码实现抢票助手
一. 代码使用Python+Splinter开发,Splinter是一个使用Python开发的开源Web应用测试工具,它可以帮你实现自动浏览站点和与其进行交互. 二. 安装好Python 3或2都可以 ...
- 知识全聚集 .Net Core 技术突破 | 简单说说工作单元
知识全聚集 .Net Core 技术突破 | 简单说说工作单元 教程 01 | 模块化方案一 02 | 模块化方案二 其他教程预览 分库分表项目实战教程 Git地址: https://github.c ...