推荐阅读
- CSDN主页
- GitHub开源地址
- Unity3D插件分享
- 简书地址
- 我的个人博客
大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有用记得一键三连哦。
一、前言
最近有项目需求,从浏览器调起来本地的exe程序,并且还要传参、传数据。
研究了一下,总结出来。
流程图如下所示:
二、正文
2-1、实现方法
浏览器实现拉起本地exe的方法,就是向系统中添加一个注册表
,注册表找到指定路径下的程序,拉起。
这个注册表就是类似于HTTP的私有协议(本地有效),可以拉起本地exe程序。
注册表如下:
[HKEY_CLASSES_ROOT\virtualcourse.test]
[HKEY_CLASSES_ROOT\test\DefaultIcon]
@="F:\test\mytest,1"
[HKEY_CLASSES_ROOT\test\shell]
[HKEY_CLASSES_ROOT\test\shell\open]
[HKEY_CLASSES_ROOT\test\shell\open\command]
@="F:\test\mytest" "%1"
DefaultIcon 是默认程序的icon位置
command 是记录程序的位置
注册表的结构:
2-2、制作注册表程序
新建个控制台程序,搭建一下UI:
编辑代码:
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
try
{
if (string.IsNullOrEmpty(txtCourseID.Text.Trim()))
{
MessageBox.Show("课程ID不能为空");
return;
}
string strPrimaryKey = "virtualcourse." + txtCourseID.Text.Trim();
RegistryKey key = Registry.ClassesRoot;
RegistryKey regPrimaryKey = key.CreateSubKey(strPrimaryKey);
regPrimaryKey.SetValue("", strPrimaryKey + " Protocol");
regPrimaryKey.SetValue("URL Protocol", "");
RegistryKey regDefaultIconKey = key.CreateSubKey(strPrimaryKey + "\\DefaultIcon");
string strExePathName = Application.StartupPath + "\\" + Application.ProductName;
regDefaultIconKey.SetValue("", strExePathName + ",1");
RegistryKey regshellKey = key.CreateSubKey(strPrimaryKey + "\\shell");
RegistryKey regshellopenKey = key.CreateSubKey(strPrimaryKey + "\\shell\\open");
RegistryKey regshellopencommandKey = key.CreateSubKey(strPrimaryKey + "\\shell\\open\\command");
regshellopencommandKey.SetValue("", string.Format("\"{0}\" \"%1\"", strExePathName));
key.Close();
MessageBox.Show("生成注册表成功!");
this.btnAddReg.Enabled = false;
this.txtCourseID.ReadOnly = true;
}
catch (Exception ex)
{
MessageBox.Show("生成注册表失败:" + ex.Message);
}
}
private void button2_Click(object sender, EventArgs e)
{
try
{
if (string.IsNullOrEmpty(txtCourseID.Text.Trim()))
{
MessageBox.Show("课程唯一ID不能为空");
return;
}
string strPrimaryKey = "virtualcourse." + txtCourseID.Text.Trim();
RegistryKey delKey = Registry.ClassesRoot;
RegistryKey regPrimaryKey = delKey.OpenSubKey(strPrimaryKey, true);
//判断要删除的regPrimaryKey是否存在
if (regPrimaryKey != null)
{
delKey.DeleteSubKeyTree(strPrimaryKey, true);
}
delKey.Close();
MessageBox.Show("删除注册表成功!");
this.btnAddReg.Enabled = true;
this.txtCourseID.ReadOnly = false;
}
catch (Exception ex)
{
MessageBox.Show("删除注册表失败:" + ex.Message);
}
}
}
}
生成解决方案:
在bin→Debug目录下运行程序:
以管理员的身份运行:
随便写入课程ID,点击生成注册表即可:
PS:也可以手动添加注册表,就是有点麻烦,在实际开发中,需要用到打包工具,将添加注册表的事项添加到安装过程中,就可以在安装完程序后,注册表也添加完成。
2-3、HTML网页调用本地exe
首先,新建个.txt文件,编辑后再改成.html后缀名即可,代码参考:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>web打开本地exe</title>
<script src="vue.js"></script>
</head>
<body>
<div id="app">
<span>请输入课程ID:</span><input type="text" name="" id="" v-model="courseId" style="width: 400px;">
<a :href="hrefValue" @click="getHrefValue" style="display: inline-block;">测试打开本地应用并传参</a>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
courseId:'',
paramValue: 'token=123456789',
hrefValue:'',
},
methods: {
getHrefValue()
{
this.hrefValue='virtualcourse.'+this.courseId+'://'+this.paramValue;
}
},
mounted() {
// this.getHrefValue();
},
})
</script>
</body>
</html>
将打包后的程序放到添加注册表的程序目录下,因为在生成注册表的时候,将这个目录记录进去了:
当然,也可以手动改这个路径。
2-4、生成Unity的exe程序
新建个Unity项目,新建场景,搭建场景:
新建脚本命名为JSCallUnity.cs,编辑代码:
using System;
using UnityEngine;
using UnityEngine.UI;
public class JSCallUnity : MonoBehaviour
{
public InputField m_Input;
void Start()
{
// 从控制台接收参数
ReadEnvironmentData();
}
private void ReadEnvironmentData()
{
//用来接收HTML发来的数据
string[] CommandLineArgs = Environment.GetCommandLineArgs();
if (CommandLineArgs.Length < 2 || CommandLineArgs[1] == "")
{
m_Input.text = "没有接收到参数";
Application.Quit();//启动时没有参数则退出
}
else
{
ParseInitData(CommandLineArgs[1]);
}
}
//解析参数
void ParseInitData(string data)
{
//解析参数
m_Input.text = data;
}
}
注意:
主要的方法就是Environment.GetCommandLineArgs();用来接收HTML发来的命令行参数数据。
官方解释:返回包含当前进程的命令行参数的字符串数组。
返回值是一个string[],当Length>1的时候就是带参数在UnityEditor模式
也就是编辑器模式会有默认参数返回,Length是大于1的
拖进去:
打包为exe:
复制到生成注册表的程序中,将命名改成生成注册表的生成的exe名字:
打开HTMl文件,输入生成的注册表的课程ID,点击测试打开本地应用:
运行结果:
后面就是对数据进行处理的事情了,这个就跟后端的程序沟通如何定义数据类型,如何解析数据即可了,这里就不展开讲了。
三、后记
本篇文章实现了从生成注册表,然后用浏览器通过注册表HTTP协议拉起本地的EXE程序。
然后Unity程序中使用了Environment.GetCommandLineArgs();
方法获取到HTML发过来的数据。
你的点赞就是对博主的支持,有问题记得留言:
博主主页有联系方式。
博主还有跟多宝藏文章等待你的发掘哦:
专栏 | 方向 | 简介 |
---|---|---|
Unity3D开发小游戏 | 小游戏开发教程 | 分享一些使用Unity3D引擎开发的小游戏,分享一些制作小游戏的教程。 |
Unity3D从入门到进阶 | 入门 | 从自学Unity中获取灵感,总结从零开始学习Unity的路线,有C#和Unity的知识。 |
Unity3D之UGUI | UGUI | Unity的UI系统UGUI全解析,从UGUI的基础控件开始讲起,然后将UGUI的原理,UGUI的使用全面教学。 |
Unity3D之读取数据 | 文件读取 | 使用Unity3D读取txt文档、json文档、xml文档、csv文档、Excel文档。 |
Unity3D之数据集合 | 数据集合 | 数组集合:数组、List、字典、堆栈、链表等数据集合知识分享。 |
Unity3D之VR/AR(虚拟仿真)开发 | 虚拟仿真 | 总结博主工作常见的虚拟仿真需求进行案例讲解。 |
Unity3D之插件 | 插件 | 主要分享在Unity开发中用到的一些插件使用方法,插件介绍等 |
Unity3D之日常开发 | 日常记录 | 主要是博主日常开发中用到的,用到的方法技巧,开发思路,代码分享等 |
Unity3D之日常BUG | 日常记录 | 记录在使用Unity3D编辑器开发项目过程中,遇到的BUG和坑,让后来人可以有些参考。 |