“.exe\”,0“此时出乎意料。”文件名中使用括号时出错

问题描述 投票:0回答:1

我正在尝试在 Windows 注册表中注册我的应用程序,但我的代码似乎有问题:

@echo off

set "APP=MyApp"
set "APP_NAME=App"
set "APP_PATH=D:\proj 100\1\test 1(64-bit).exe"
set "APP_ICON=\"%APP_PATH%\",0"
set "APP_ARGS=\"%APP_PATH%\" \"%%1\""

if not exist "%APP_PATH%" (

echo ERROR: "%APP_PATH%" not found.

) else (


reg add "HKLM\Software\Classes\%APP%HTML" /v "" /t REG_SZ /d "%APP_NAME% Document" /f
reg add "HKLM\Software\Classes\%APP%HTML\DefaultIcon" /v "" /t REG_SZ /d "%APP_ICON%" /f
reg add "HKLM\Software\Classes\%APP%HTML\shell\open\command" /v "" /t REG_SZ /d "%APP_ARGS%" /f

)

pause

我不断收到此错误

.exe\",0" was unexpected at this time.

编辑: 我在测试代码后更改了文件名输出,原来的名称是

test 1(64-bit).exe
,所以显然只有当文件名/路径有括号时才会发生。我试图逃避角色,但没有成功。

batch-file
1个回答
1
投票

发布的批处理代码不起作用,因为命令行中文件名中的

)
所有环境变量引用都已展开

reg add "HKLM\Software\Classes\MyAppHTML\DefaultIcon" /v "" /t REG_SZ /d "\"D:\proj 100\1\test 1(64-bit).exe\",0" /f
由于位于双引号参数字符串之外,因此

被解释为

else
命令块的结尾。对于 Windows 命令处理器,REG 选项
/d
之后的第一个参数字符串是
"\"
,因此
D:\proj 100\1\test 1(64-bit)
位于双引号参数字符串之外。
另请参阅:Windows 命令解释器 (CMD.EXE) 如何解析脚本?

以下避免命令块的批处理代码会更好:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "APP_FILE=D:\proj 100\1\test 1(64-bit).exe"
if not exist "%APP_FILE%" echo ERROR: "%APP_FILE%" not found.& exit /B 1

set "RegExe=%SystemRoot%\System32\reg.exe"
if exist %SystemRoot%\Sysnative\reg.exe set "RegExe=%SystemRoot%\Sysnative\reg.exe"

set "APP=MyApp"
set "APP_NAME=App"
set "APP_ICON=\"%APP_FILE%\",0"
set "APP_ARGS=\"%APP_FILE%\" %%1"

%RegExe% ADD "HKLM\Software\Classes\%APP%HTML" /f /ve /t REG_SZ /d "%APP_NAME% Document" >nul
if errorlevel 1 echo ERROR: %~nx0 must be run as administrator.& exit /B
%RegExe% ADD "HKLM\Software\Classes\%APP%HTML\DefaultIcon" /f /ve /t REG_SZ /d "%APP_ICON%" >nul
%RegExe% ADD "HKLM\Software\Classes\%APP%HTML\shell\open\command" /f /ve /t REG_SZ /d "%APP_ARGS%" >nul

endlocal

首先定义环境变量

APP_FILE
,然后通过将错误消息打印到标准输出句柄来检查该文件是否存在,并在应用程序可执行文件不存在时以错误退出代码 1 退出批处理文件的处理。

批处理文件设计为在 32 位和 64 位 Windows 上运行,并在 64 位 Windows 上运行,并且始终在目录

reg.exe
中以 64 位
%SystemRoot%\System32
运行,即使批处理文件正在由 32 位
cmd.exe
处理,目录
%SystemRoot%\SysWOW64
。请参阅 Microsoft 文档页面:

  1. WOW64 实施细节
  2. 文件系统重定向器
  3. 受 WOW64 影响的注册表项

使用选项

/ve
而不是
/v ""
,如在命令提示符窗口中运行
reg add /?
时的使用帮助输出所解释的。

%1
周围的双引号被删除,因为 Windows 文件资源管理器会在必要时将双引号添加到传递给可执行文件的参数字符串中,就像包含空格字符的参数字符串一样。但是,也可以使用:

set "APP_ARGS=\"%APP_FILE%\" \"%%1\""

批处理文件成功添加到 Windows 注册表中:

REGEDIT4

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\MyAppHTML]
@="App Document"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\MyAppHTML\DefaultIcon]
@="\"D:\\proj 100\\1\\test 1(64-bit).exe\",0"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\MyAppHTML\shell]

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\MyAppHTML\shell\open]

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\MyAppHTML\shell\open\command]
@="\"D:\\proj 100\\1\\test 1(64-bit).exe\" %1"

上面的批处理文件在分配给环境变量的完全限定文件名上无法正确工作

APP_FILE
包含一个&符号
&
,就像下面的批处理文件中使用的路径
C:\Temp\Development & Test!
一样,使用延迟变量扩展来处理这样的也是不寻常的道路。

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "APP_FILE=C:\Temp\Development & Test!\test 1(64-bit).exe"
if not exist "%APP_FILE%" echo ERROR: "%APP_FILE%" not found.& exit /B 1

set "RegExe=%SystemRoot%\System32\reg.exe"
if exist %SystemRoot%\Sysnative\reg.exe set "RegExe=%SystemRoot%\Sysnative\reg.exe"

setlocal EnableDelayedExpansion
set "APP=MyApp"
set "APP_NAME=App"
set "APP_ICON=\"!APP_FILE!\",0"
set "APP_ARGS=\"!APP_FILE!\" %%1"
rem set "APP_ARGS=\"!APP_FILE!\" \"%%1\""

%RegExe% ADD "HKLM\Software\Classes\%APP%HTML" /f /ve /t REG_SZ /d "%APP_NAME% Document" >nul
if errorlevel 1 echo ERROR: %~nx0 must be run as administrator.& exit /B
%RegExe% ADD "HKLM\Software\Classes\%APP%HTML\DefaultIcon" /f /ve /t REG_SZ /d "!APP_ICON!" >nul
%RegExe% ADD "HKLM\Software\Classes\%APP%HTML\shell\open\command" /f /ve /t REG_SZ /d "!APP_ARGS!" >nul

endlocal
endlocal

请注意,

if
echo
exit
都不会修改动态变量
ERRORLEVEL
的值,因此第二个
exit /B
也会导致批处理文件处理退出,并显示错误退出代码
1
reg.exe
设置。

要了解所使用的命令及其工作原理,请打开命令提示符窗口,执行以下命令,并完整、仔细地阅读每个命令显示的帮助页面。

  • echo /?
  • endlocal /?
  • exit /?
  • if /?
  • reg /?
  • reg add /?
  • rem /?
  • set /?
  • setlocal /?

另请参阅:

© www.soinside.com 2019 - 2024. All rights reserved.