".exe\",0" 此时出现意外。"在文件名中使用括号时出错

".exe\",0" Was unexpected at this time." Error when using parentheses in file name

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

@echo off

set "APP=MyApp"
set "APP_NAME=App"
set "APP_PATH=D:\proj 100\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,所以显然它只发生在文件 name/path 有括号时。我试图转义字符,但没有成功。

发布的批处理代码不起作用,因为命令行中的文件名中有 ),所有环境变量引用都已展开

reg add "HKLM\Software\Classes\MyAppHTML\DefaultIcon" /v "" /t REG_SZ /d "\"D:\proj 100\test 1(64-bit).exe\",0" /f

被解释为 else 命令块的结尾,因为在双引号参数字符串之外。对于 Windows 命令处理器,REG 选项 /d 之后的第一个参数字符串是 "\",因此 D:\proj 100\test 1(64-bit) 在双引号之外参数字符串。
另见:How does the Windows Command Interpreter (CMD.EXE) parse scripts?

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

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "APP_FILE=D:\proj 100\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 上运行,始终在目录 [=22] 中运行 64 位 reg.exe =] 即使在目录 %SystemRoot%\SysWOW64 中由 32 位 cmd.exe 处理的批处理文件。请参阅 Microsoft 文档页面:

  1. WOW64 Implementation Details
  2. File System Redirector
  3. Registry Keys Affected by WOW64

使用选项 /ve 而不是 /v "",如命令提示符 window 中 运行 reg add /? 上的用法帮助输出所解释的那样。

%1 周围的双引号被删除,因为 Windows 文件资源管理器将自己的双引号添加到传递给可执行文件的参数字符串中,如果有必要,就像在包含 [=122 的参数字符串上一样=] 字符。但是,也可以使用:

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

请注意,ifechoexit 都不会修改动态变量 ERRORLEVEL 的值,因此第二个 exit /B 的结果也会在批处理文件处理的退出中,错误退出代码 1reg.exe.

设置

为了了解使用的命令及其工作原理,请打开 command prompt window,在其中执行以下命令,并仔细阅读为每个命令显示的所有帮助页面。

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

另请参阅: