前端带参数启动外部exe并接收返回值的实现

提示:适用于非IE浏览器,(大家都知道ActiveXObject可以做到,但是人家是Microsoft扩展,仅在Internet Explorer中支持






前言

       最近有个需求是要前端调用浏览器外部的exe文件,而且还要传参和接受返回值,刚开始听到需求的时候是崩溃的(菜鸟内心OS:这也能做?
        查了很多资料之后发现确实行,大概有两种方法:分别适用于
IE和非IE浏览器

提示:以下本篇文章正文内容适用于非IE浏览器,例chrome,下面案例可供参考





一、创建.reg文件添加注册表

在web端启动本地应用程序的可以操作注册表,先在注册表注册一个自定义的URL Protocol协议,再利用URL Protocol实现web端调用本地exe,具体操作如下:

首先新建一个txt或者其他格式,写入以下内容:

示例1:新建Start.txt(不带参数启动)

Windows Registry Editor Version 5.00
//  表示注册表工具的版本信息
[HKEY_CLASSES_ROOT\Start]
// 表示的是注册表的HKEY_CLASSES_ROOT下新增一个Start项
"URL Protocol"="D:\\Program Files\\WeGame\\wegame.exe"
// 在网页中要打开的exe应用程序的绝对路径
@="Start Protocol"
// 协议名称,可以是任意字符串
[HKEY_CLASSES_ROOT\Start\DefaultIcon]
// 在Start下新增一个分支
@="D:\\Program Files\\WeGame\\wegame.exe"
// 在网页中要打开的exe应用程序的绝对路径
[HKEY_CLASSES_ROOT\Start\shell]
// 在Start下新建项shell
[HKEY_CLASSES_ROOT\Start\shell\open]
// 在shell下新建项open
[HKEY_CLASSES_ROOT\Start\shell\open\command]
// 在open下新建项command
@="\"D:\\Program Files\\WeGame\\wegame.exe\""
// 在网页中要打开的exe应用程序的绝对路径
// 注:使用时把注释删除

示例2:(带参数启动) 

Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\Start]
"URL Protocol"="D:\\Program Files\\WeGame\\wegame.exe"
@="Start Protocol"
[HKEY_CLASSES_ROOT\Start\DefaultIcon]
@="D:\\Program Files\\WeGame\\wegame.exe,1"
[HKEY_CLASSES_ROOT\Start\shell]
[HKEY_CLASSES_ROOT\Start\shell\open]
[HKEY_CLASSES_ROOT\Start\shell\open\command]
@="\"D:\\Program Files\\WeGame\\wegame.exe\" \"%1\""

 注:主要区别在第六行和最后一行

写完之后将Start.txt重命名为Start.reg,然后双击弹出的提示框都选择“是/确定”

 注: 每次修改该文件之后都需要双击确定添加到注册表中





二、HTML部分





1.不带参数

代码如下(示例):

<template>
  <div>
    <a href="Start://">WeGame启动</a>
  </div>
</template>





2.携带参数启动

代码如下(示例):

<template>
  <div>
    <a href="Start://parameter">WeGame启动</a>
  </div>
</template>

此处parameter为传给exe的参数,如果需要传递多个参数需要自定义分隔符供exe识别分割。

以上就可以成功启动web网页的外部本机应用程序了! 

三、接收返回值

截至目前为止需求算是完成了一半,但是如果还需要该应用程序的执行结果(返回数据)呢?毕竟不会有谁写个web网页中的链接来启动WeGame。

1、写入文件,用户读取本地文件

第一条思路是将exe的返回结果写入一个本地文件(例:txt),然后用户读取这个文件。

但是出于安全和隐私的原因,JavaScript 不能直接访问本地文件(无法绕过用户直接操作)

只能通过:

<input type="file">

用户自行选择本地文件,然后利用FileReader对象来获取文件的相关内容。但是如果不想让用户来做这一步直接获得应用程序的返回结果,这显然是不行的。

2、搭建本地服务,通过接口传输数据

既然无法绕过用户获取本地文件信息,那么让本地应用直接把数据发给客户端不就行了?

大概步骤如下:

一、搭建本地服务,直接在本地调取到返回结果并提供接口

二、web网页通过接口访问本地服务获取数据

JavaScript部分示例:

axios({
    url: 'http://127.0.0.1:5000/.../...',
    method: 'POST',
    data: data
}).then(function(res) {
    console.log(res.data)
})

搭建了本地服务之后,之前通过操作注册表来传递参数的方法也可以做相应修改(直接通过接口传参数),.reg文件用来启动本地服务即可。 






总结

在非IE浏览器上想要直接获取本地文件或数据是困难的,饶了这么一大圈终于实现了。

本文仅仅是简单的应用,我也是一只前端小白,如果有更好的方法或者本文有错误和不妥之处希望各位大佬批评指正。

参考链接:JS 通过注册表调用启动本地软件_weixin_30849591的博客-CSDN博客

  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
VC(Visual C++)可以通过调用外部的.exe文件并传入参数,然后获取该程序的返回值。以下是一个简单的示例代码: ```cpp #include <windows.h> #include <iostream> int main() { std::string programPath = "C:\\path\\to\\program.exe"; std::string parameters = "param1 param2 param3"; // 创建一个匿名管道,用于接收程序的输出 HANDLE hReadPipe, hWritePipe; SECURITY_ATTRIBUTES securityAttributes; securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); securityAttributes.bInheritHandle = TRUE; securityAttributes.lpSecurityDescriptor = NULL; if (!CreatePipe(&hReadPipe, &hWritePipe, &securityAttributes, 0)) { std::cerr << "无法创建管道!" << std::endl; return -1; } // 启动程序并将输出重定向到管道 STARTUPINFO startupInfo; PROCESS_INFORMATION processInformation; ZeroMemory(&startupInfo, sizeof(startupInfo)); ZeroMemory(&processInformation, sizeof(processInformation)); startupInfo.cb = sizeof(startupInfo); startupInfo.hStdInput = NULL; startupInfo.hStdOutput = hWritePipe; startupInfo.hStdError = hWritePipe; startupInfo.dwFlags |= STARTF_USESTDHANDLES; if (!CreateProcess(NULL, const_cast<LPSTR>(programPath.c_str()), NULL, NULL, TRUE, 0, NULL, NULL, &startupInfo, &processInformation)) { std::cerr << "无法启动程序!" << std::endl; CloseHandle(hReadPipe); CloseHandle(hWritePipe); return -1; } // 等待程序结束并获取返回值 WaitForSingleObject(processInformation.hProcess, INFINITE); DWORD exitCode; GetExitCodeProcess(processInformation.hProcess, &exitCode); // 读取程序输出 char buffer[1024]; DWORD bytesRead; std::string output; while (ReadFile(hReadPipe, buffer, sizeof(buffer), &bytesRead, NULL) && bytesRead > 0) { output.append(buffer, bytesRead); } // 关闭句柄 CloseHandle(hReadPipe); CloseHandle(hWritePipe); CloseHandle(processInformation.hProcess); CloseHandle(processInformation.hThread); std::cout << "程序返回值:" << exitCode << std::endl; std::cout << "程序输出:" << std::endl; std::cout << output << std::endl; return 0; } ``` 上述代码首先使用`CreatePipe`函数创建了一个匿名管道,然后使用`CreateProcess`函数启动目标程序,并将其标准输出重定向到管道。接下来,使用`WaitForSingleObject`函数等待程序结束,并通过`GetExitCodeProcess`函数获得程序的返回值。最后,使用`ReadFile`函数读取管道中的输出,并关闭相关的句柄。 这样,我们就可以通过VC调用外部的.exe文件并传入参数,并获取到该程序的返回值
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值