将变量传递给setlocal代码

时间:2015-11-24 15:49:48

标签: windows batch-file cmd

在Windows批处理文件中编写脚本时,有时正确执行脚本需要使用setlocal命令。我关于使用setlocal的主要抱怨是,我经常表现出复杂的& if语句,我在该段代码中设置变量值。发出命令endlocal时,这些设置会丢失。

到目前为止,我通过将变量值回显到setlocal段中的暂存文件中然后将值读回endlocal之后的变量来解决此问题。但是,似乎应该有一个更优雅的解决方案。

如果仅使用一个或多个set语句,建议的答案提供了一种绕过问题的便捷方法。但是,当setlocal到位以允许for循环在执行时正确扩展变量名而不是解析时,链接的答案不提供解决方案。在我的情况下,我还有if语句逻辑树来进一步检查该信息到set许多不同的可能变量值。链接的解决方案无法解决这种情况。

此代码应检查安装包的版本号。它是从另一个需要版本号才能正常运行的脚本调用的。我们知道包是使用[应用程序] [版本号] .msi的形式命名的。 [版本号]可以是以下任何一种:

  • 7
  • 7.5
  • 9
  • 9.5
  • 10
  • 10.1

指定目录中可能存在多个安装包,因此查看所有安装包并在目录中选择最高版本非常重要。

我继承并扩展了代码以正确处理10& 10.1版本。如果没有setlocal有更好的方法来做到这一点(例如,我已经考虑过重写以使用案例陈述),我很乐意看到更好的解决方案。

但是,我仍然有兴趣学习如何将变量传递出setlocal / endlocal段。

setlocal enabledelayedexpansion

for /f %%a in ('dir /b program*.MSI') do (
    set FileName=%%a
    set tst1=!FileName:~4,3!
    if "!tst1!" == "msi" (
        rem Only true if it has a 1 digit number (e.g. "9")
        set MAIN_VERSION=!FileName:~2,1!
    ) else (
        set tst2=!FileName:~5,3!
        if "!tst2!" == "msi" (
            rem Only true if it has a 2 digit version number (e.g. "10")
            set MAIN_VERSION=!FileName:~2,2!
        ) else (
            ... lots more code ...
        )
    )
)
rem Write results out to a file for temporary storage.  This particular
rem form of echo is required to ensure there are no trailing spaces, CR,
rem or LF
echo|set /P ="!MAIN_VERSION!" > %USERPROFILE%\UGV.txt

rem End local variables 
endlocal

rem Read the correct version out of our temporary storage file
set /p MAIN_VERSION=<%USERPROFILE%\UGV.txt

如何在不使用临时文件的情况下从Windows批处理脚本MAIN_VERSION / setlocal代码段传递变量(例如上面的endlocal)?

1 个答案:

答案 0 :(得分:3)

要保留setlocal / endlocal范围内的变量,存在不同的解决方案。

这取决于您应该使用哪种情况。

1)简单

只使用简单内容的括号块之外的,但可以产生特殊字符的问题,例如!^"

setlocal 
set localVar=something simple
...
(
  endlocal
  set "out=%localVar%"
)
set out

2)中等

也可以在块中使用并且可以处理大多数字符,但可能会因!^和换行/回车而失败

if 1==1 (
  setlocal EnableDelayedExpansion
  set "localVar=something medium nasty & "^&"

  for /F "delims=" %%V in ("!localVar!") DO (    
      endlocal
      set "out=%%V"
  )
)
set out

3)高级

适用于任何情况下的所有内容
SO: preserving exclamation marks in variable between setlocals batch