这看起来很简单,但结果却是如此痛苦。
在Windows 7上,我可以将以下内容粘贴到命令提示符中,并将ProgramFiles(x32)
设置为%programfiles%
或%programfiles(x86)%
,然后回显它设置为:
%comspec% /c if exist "%programfiles%" (set "ProgramFiles(x32)=%programfiles%") else (set "%ProgramFiles(x32)=%programfiles(x86)%") && set Program && echo %programfiles(x32)% && pause
然而,当将这个相同的命令放入快捷方式时,我得到了这个:
发生了什么事?
答案 0 :(得分:2)
首先,我将从命令提示符运行代码的角度出发。在该上下文中,您的代码有4个问题。
1)我认为这没有多大区别,但我相信你总是希望在命令行中执行最后3个命令。但是您使用了条件&&
运算符,如果前面的命令成功,它只执行以下命令。我相信您想要使用&
。
2)你有一个优先问题。您想要执行IF / ELSE语句,然后在完成后您想要执行3个附加命令。但是,您编写的3个附加命令被认为是IF语句的ELSE子句的一部分。在整个IF / ELSE语句中需要一组额外的括号。
(if exist "%programfiles%" (set "ProgramFiles(x32)=%programfiles%") else (set "ProgramFiles(x32)=%programfiles(x86)%")) & ...
3)您希望%comspec% /c
之后的所有内容都成为传递给CMD.EXE的命令行的一部分。但是,当您在命令行控制台中运行整个语句时,对CMD.EXE的调用将在&
的第一次出现时结束。该行的其余部分由父命令窗口执行,而不是通过调用CMD.EXE。您需要将&
字符转义为^&
,否则引用要传递的整行。
4)解析行时会发生%VAR%扩展,并且在执行任何命令之前一次解析整个命令行。因此,您看到的%ProgramFiles(x32)%的值是执行任何命令之前的值。通常没有定义该值,并且您处于命令行上下文中,因此将打印具有百分比的原始字符串。修复方法是使用CALL ECHO %^ProgramFiles(x32)%
或使用/V:ON
选项启用延迟展开,然后使用ECHO !ProgramFiles(x32)!
。插入符号是为了确保字符串传递给CMD.EXE而不是在父命令行中展开(以防已经定义了ProgramFiles(x32))。
以下各项应该从命令提示符中提供您要查找的结果:
%comspec% /v:on /c "(if exist "%programfiles%" (set "ProgramFiles(x32)=%programfiles%") else (set "%ProgramFiles(x32)=%programfiles(x86)%")) & set Program & echo !programfiles(x32)!& pause"
%comspec% /c "(if exist "%programfiles%" (set "ProgramFiles(x32)=%programfiles%") else (set "%ProgramFiles(x32)=%programfiles(x86)%")) & set Program & call echo %^programfiles(x32)%& pause"
%comspec% /v:on /c (if exist "%programfiles%" (set "ProgramFiles(x32)=%programfiles%") else (set "%ProgramFiles(x32)=%programfiles(x86)%")) ^& set Program ^& echo !programfiles(x32)!^& pause
%comspec% /c (if exist "%programfiles%" (set "ProgramFiles(x32)=%programfiles%") else (set "%ProgramFiles(x32)=%programfiles(x86)%")) ^& set Program ^& call echo %^programfiles(x32)%^& pause
从快捷方式执行时情况有所不同。快捷方式没有父命令提示符,因此上述第3点不适用。 <{1}}字符不应该被转义,尽管整个命令行仍然可以被引用。
第1点,第2点和第4点对于快捷方式仍然有效。
所以以下陈述都可以作为捷径:
&
比较两组语句,其中只有两组对两种语境都有效。以下两个语句在命令行和快捷方式中都有效:
%comspec% /v:on /c "(if exist "%programfiles%" (set "ProgramFiles(x32)=%programfiles%") else (set "%ProgramFiles(x32)=%programfiles(x86)%")) & set Program & echo !programfiles(x32)!& pause"
%comspec% /c "(if exist "%programfiles%" (set "ProgramFiles(x32)=%programfiles%") else (set "%ProgramFiles(x32)=%programfiles(x86)%")) & set Program & call echo %^programfiles(x32)%& pause"
%comspec% /v:on /c (if exist "%programfiles%" (set "ProgramFiles(x32)=%programfiles%") else (set "%ProgramFiles(x32)=%programfiles(x86)%")) & set Program & echo !programfiles(x32)!& pause
%comspec% /c (if exist "%programfiles%" (set "ProgramFiles(x32)=%programfiles%") else (set "%ProgramFiles(x32)=%programfiles(x86)%")) & set Program & call echo %^programfiles(x32)%& pause
上面的两个语句在从命令提示符发出或作为我的Vista计算机上的快捷方式时给出以下结果:
%comspec% /v:on /c "(if exist "%programfiles%" (set "ProgramFiles(x32)=%programfiles%") else (set "%ProgramFiles(x32)=%programfiles(x86)%")) & set Program & echo !programfiles(x32)!& pause"
%comspec% /c "(if exist "%programfiles%" (set "ProgramFiles(x32)=%programfiles%") else (set "%ProgramFiles(x32)=%programfiles(x86)%")) & set Program & call echo %^programfiles(x32)%& pause"