java注册自定义url协议处理

2 篇文章 0 订阅
1 篇文章 0 订阅

    这几天研究了自定义url处理的东西, 过程挺曲折的, 这里记录一下.
    自定义url处理可以实现通过网页链接调用客户端后台程序的作用, 在有的时候很有用. 比如说mailto协议(mailto://aaa)可以调用邮件客户端发送邮件, 很方便. 在公司实现的功能是通过网页选中一些文本, 右键执行, 可以用url调用的方式把命令发给后台程序, 后台程序再通过脚本发送给远程linux服务器, 执行命令, 免去了每次都需要输入密码登录服务器的时间, 随便选择一个命令都可以随时运行, 很方便.
    url有个限制需要注意: 一般浏览器限制url的长度为2048个字符, 中文可能会占多个字符,每个浏览器大同小异, 所以不适合用来处理过多参数的文本. 且url需要经过encodeURIComponent编码,否则后台bat可能会识别错误.
    之前在公司写好了程序, 在家里重新来一遍发现好多坑, 公司电脑是win7的, 家里是win10的, 这个差别还是很大. 下面说说如何自定义.
首先win+r执行regedit进入注册表, 找到HKEY_CLASSES_ROOT\http这个,右键导出.
先找个模板抄一下
在这里插入图片描述
打开导出的注册表文件, 项目有很多, 但其实只需要两个
在这里插入图片描述
之前在win7上写的时候没加上面的URL Protocol也可以, win10就必须有, 不然浏览器识别不出来这个协议, 点击没反应. 上面是http协议的注册表, 如果要自定义myurl协议, 只需要把http改为myurl, 执行命令自定义就可以了.
知道了注册表项, 下面开始操作注册表.

package work.drqf;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.file.Paths;
import java.util.Arrays;

public class Test {

	public static void main(String[] args) throws Exception {
		// 如果不传参数, 表示首次执行, 就录入注册表信息.
		if (args.length == 0 || "".equals(args[0])) {
			registerUrlHandler();
			System.out.println("-----Register Url Handler success!-----");
		} else {
			// 通过注册表执行了程序, 这里打印出参数. 可以添加其他自定义逻辑
			System.out.println(Arrays.toString(args));
			System.out.println("-----called by Url!-----");
		}
	}

	private static void registerUrlHandler() throws Exception {
		Runtime runtime = Runtime.getRuntime();

		String curPath = Paths.get("./").toAbsolutePath().getParent().toString();
		String registerKey = "HKEY_CLASSES_ROOT\\myurl\\shell\\open\\command";

		// 通过runtime执行cmd命令
		Process proc = runtime.exec("reg query " + registerKey);

		String content = readStream(proc.getInputStream());
		System.out.println(content);
		// 如果注册的执行路径是当前路径, 表示已经注册好了, 退出, 否则表示移动了软件位置, 重新注册.
		if (content.contains(curPath)) {
			return;
		}

		// String javaPath = System.getenv("JAVA_HOME") + "\\bin\\java.exe";
		// 添加 URL Protocol项
		String cmd0 = "reg add \"HKEY_CLASSES_ROOT\\myurl\" /v \"URL Protocol\" /d \"\" /f";
		runtime.exec(cmd0);

		// 添加命令
		String cmd = "reg add \"" + registerKey + "\" /ve /d \"\\\"" + curPath
				+ "\\runUrlCallBack.bat\\\" \\\"%1\\\"\" /f";
		// System.out.println(cmd);
		Process procAdd = runtime.exec(cmd);

		procAdd.waitFor();
		System.out.println(readStream(procAdd.getErrorStream()));
		System.out.println(readStream(procAdd.getInputStream()));
	}

	private static String readStream(InputStream is) throws IOException {
		try (BufferedReader br = new BufferedReader(new InputStreamReader(is));) {
			String content = "";
			String line = "";
			while ((line = br.readLine()) != null) {
				content += line;
			}
			return content;
		}
	}
}

上面的代码, 解释一下reg命令. reg命令是windows操作注册表专用的, 可以在cmd命令行通过reg /? 以及reg add /?等查看帮助.
在这里插入图片描述
用法就是:

reg query "HKEY_CLASSES_ROOT\myurl\shell\open\command"
reg add "HKEY_CLASSES_ROOT\myurl\shell\open\command" /ve /d "\"D:\tmp\runUrlCallBack.bat\" \"%1\"" /f

其中%1表示的是调用时的整个url, 不仅仅参数部分, 实际是: myurl://aaa=0&bbb=1这种格式.
最终注册表值看下图.
reg query命令没什么问题. 但是reg add要注意:
(1). /ve选项表示名称为默认, 在win7上可以写成/v “” , 但win10这样写会报错, 必须用/ve
(2). 注意key和data要加引号, data中有嵌套引号要记得转义, 简单的转义是上面的例子.
(3). 上面的转义是在cmd中执行时的转义用法, win7只有cmd, 所以没什么问题, 但是win10分cmd和power shell两个命令行工具, 这两个工具的用法不一样, power shell的转义是用两个双引号"“而不是\”, 所以上面的对应的reg add就是:

 reg add "HKEY_CLASSES_ROOT\myurl\shell\open\command" /ve /d """D:\tmp\runUrlCallBack.bat"" ""%1""" /f

所以一定要分清楚是用cmd.exe来执行命令, 还是用powershell来执行. win10直接右键用的是cmd.exe
在这里插入图片描述

介绍说完了, 开始搞代码.
把上面的java代码导出为UrlCallBack.jar放在D:\tmp路径下, 我这里的包名是work.drqf, 记得如果你的包名和我的不一样, 等会儿执行命令也要对应修改.
在这里插入图片描述
在D:\tmp下新建一个runUrlCallBack.bat文件, bat文件名和上面java文件加到注册表里的名字一样. 内容如下:

%~d0
cd %~dp0
java -cp .\UrlCallBack.jar work.drqf.Test %1%
pause

前两句是cd到当前目录, 然后执行java命令,传递参数. 这里我为了方便查看控制台结果, 所以pause停下了, 正式代码可以去掉这个.
首次需要手动执行bat登录注册表.执行这个bat在win7下可以直接运行, 在win10下需要管理员权限运行. 第一次执行时, %1%参数为空, 所以java代码会查询并登录注册表.
然后就可以在浏览器里通过url调用了.
写个html文件 放个链接, 代码如下:

<!doctype html>
<html lang="en">
 <head>
  <meta charset="UTF-8">
  <meta name="Generator" content="EditPlus®">
  <meta name="Author" content="">
  <meta name="Keywords" content="">
  <meta name="Description" content="">
  <title>Document</title>
 </head>
 <body>
  <a href="myurl://aaa=0&bbb=1">myurl</a>
 </body>
</html>

运行, 点击
在这里插入图片描述
在这里插入图片描述
大功告成.

Java里面也有转义, 再加上原本的转义很容易把人绕晕,所以一定要看清楚.
为什么要通过java操作注册表呢?是因为我想让软件位置变更的时候通过java自动切换路径, 而直接用注册表文件reg的话就得写死了, 如果换台机器就得手动更改路径, 很麻烦. 用java虽然写起来费力一点但是用起来是傻瓜用法, 很方便.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值