工作中,遇到一个这样的需求:

  • 应用需要提供绿色安装版;
  • 在应用从未启动过的状态下可以通过 URL scheme 启动;
  • 实现以上两点要求的方式为bat脚本写注册表。

首先我们的应用之前是有以下这样一个 install.nsh 脚本会在应用安装时被执行,

1
2
3
4
5
6
7
8
9
10
# install.nsh
!macro customInstall
DetailPrint "Register evehq-ng URI Handler"
DeleteRegKey HKCR "test-app"
WriteRegStr HKCR "test-app" "" "URL:test-app"
WriteRegStr HKCR "test-app" "URL Protocol" ""
WriteRegStr HKCR "test-app\shell" "" ""
WriteRegStr HKCR "test-app\shell\open" "" ""
WriteRegStr HKCR "test-app\shell\open\command" "" "$INSTDIR\${APP_EXECUTABLE_FILENAME} %1"
!macroend

本次需求可以理解为将以上脚本翻译为 bat 脚本。根据使用需求,设计通过 bat 脚本参数传入应用目录来满足使用需求。这样给出第一版 bat 脚本:

1
2
3
4
5
6
7
8
9
10
:: register.bat
@echo off
REG DELETE HKCR\test-app /f
REG ADD HKCR\test-app /d "URL:test-app"
REG ADD HKCR\test-app /v "URL Protocol"
REG ADD HKCR\test-app\shell
REG ADD HKCR\test-app\shell\open
REG ADD HKCR\test-app\shell\open\command /d %1
pause
@echo on

当提供给需求方使用时,需求方提出以下问题:

  1. 脚本执行完毕后命令行窗口需要直接关闭;
  2. 脚本虽然可以实现打开应用,但是第一次不能实现通过 URL scheme 携带参数登录。

第一个问题很好解决,直接把 pause 这行代码去掉就OK了。

解决第二个问题的时候,通过对比应用通过启动器安装之后 install.nsh 执行得到的注册表内容

和第一版 register.bat 执行得到的注册表内容

发现在 HKCR\test-app\shell\open\command 这一项上前后不一致,而通过Review项目代码,也发现在通过 URL scheme 启动的流程中有对 process.argv[1] 进程参数的处理。

再次回顾 install.nsh 的代码,毫无疑问,问题出在了对

1
WriteRegStr HKCR "test-app\shell\open\command" "" "$INSTDIR\${APP_EXECUTABLE_FILENAME} %1"

这一句的翻译上。我们仅仅翻译了 $INSTDIR\${APP_EXECUTABLE_FILENAME} 这一部分对应着的应用目录,而丢掉了 %1 ,导致我们在通过 URL scheme 打开应用时无法接收参数。

知道了问题,就开始编写第二版 bat 脚本,由于对于 bat 脚本编写语法的不熟悉,我没能100%还原 install.nsh 执行的结果,写入的结果总是无法包含双引号。
初步想法由以下脚本得到与 install.nsh 执行一致的结果。

1
REG ADD HKCR\test-app\shell\open\command /d "%1 "%%1""

但执行时总是会得到以下报错

大致错误应该是由双引号的转义使用不正确导致的。经过查阅资料,反复尝试,暂时没能找到通过 bat 脚本向注册表正确转义写入成对双引号的方法,这时观察到第一版的写入结果没有包含双引号也可以正常解析使用,那么不包含双引号是否可以呢?由此得出第二版 bat 脚本:

1
2
3
4
5
6
7
8
9
10
:: register_v2.bat
@echo off
REG DELETE HKCR\test-app /f
REG ADD HKCR\test-app /d "URL:test-app"
REG ADD HKCR\test-app /v "URL Protocol"
REG ADD HKCR\test-app\shell
REG ADD HKCR\test-app\shell\open
SET INPARAM=%1
SET INPARAM=%INPARAM:~1,-1%
REG ADD HKCR\test-app\shell\open\command /d "%INPARAM% %%1"

经过测试,使用效果与 install.nsh 写入的注册表相同。

不过,还是没能搞懂如何使用 bat 脚本向注册表写入带有成对双引号的值,如果有大佬看到此篇文章还望不吝赐教