在复合 IF 语句中使用带括号的环境变量,如 %ProgramFiles(x86)% 会引发意外错误

Using environment variable with parens, like %ProgramFiles(x86)% in a compound IF-statement raises unexpected errors

我尝试了以下场景 with/without delayedExpansion(编辑:Squashman 在评论中解释说不需要延迟扩展)

当我尝试设置使用 !ProgramFiles(x86)!%ProgramFiles(x86)%

的环境变量时收到不可预知的错误

示例:

@echo off
rem With or without this, with/without "!" or "%", fails on "SET"
setlocal EnableDelayedExpansion

if exist "!ProgramFiles(x86)!\Microsoft Visual Studio\Installer" (
    set INSTALLVS=!ProgramFiles(x86)!\Microsoft Visual Studio\Installer
)

echo !INSTALLVS!

结果:

d:\test>runbatch.cmd
!\Microsoft was unexpected at this time.

添加引号有效(如 SET="%ProgramFile...",但后来我 运行 遇到了麻烦,在组合路径时不得不删除引号),或者临时变量有效:

@echo off
rem Works correctly
setlocal EnableDelayedExpansion

set INSTALLTMP=!ProgramFiles(x86)!\Microsoft Visual Studio\Installer

if exist "!INSTALLTMP!" (
    set INSTALLVS=!INSTALLTMP!
    set INSTALLTMP=
)

echo !INSTALLVS!

发生这种情况:

不会发生在什么时候:

我在这里做错了什么/误解了什么?

问题出在关闭 IF 块的右括号。有没有延期扩张都没有关系。

  • 某些语句,如 echorem:: 在包含右括号时可以正常工作。
  • 大多数其他语句,如 setcopygotomd 等都不起作用,没有引号的右括号将关闭IF 块。
  • 出于同样的原因,复合语句(如 echo hello > foo(32).txt)不起作用。
  • 如果右括号是您使用的环境变量名称的一部分,它也可能会使 IF 块短路
  • 作为嵌套 IF 或 DO 块一部分的右括号是安全的,允许嵌套

解决方案是在命令允许的情况下将右括号放在引号中,或者将其转义,即:!ProgramFiles^(x86^)!(仅适用于 enableDelayedExpansion)。

例如:

@echo off
setlocal enabledelayedexpansion

if exist "!ProgramFiles(x86)!\Microsoft Visual Studio\Installer" (
    set "INSTALLVS=!ProgramFiles(x86)!\Microsoft Visual Studio\Installer"
)

echo !INSTALLVS!

if exist "!ProgramFiles(x86)!\Microsoft Visual Studio\Installer" (
    set INSTALLVS=!ProgramFiles^(x86^)!\Microsoft Visual Studio\Installer
)

echo %INSTALLVS%

setlocal disabledelayedexpansion

if exist "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer" (
    set "INSTALLVS=%ProgramFiles(x86)%\Microsoft Visual Studio\Installer"
)

echo %INSTALLVS%

pause

输出

C:\Program Files (x86)\Microsoft Visual Studio\Installer
C:\Program Files (x86)\Microsoft Visual Studio\Installer
C:\Program Files (x86)\Microsoft Visual Studio\Installer
Press any key to continue . . .