【问题标题】:Conditional If Statement Syntax in Batch批量条件 if 语句语法
【发布时间】:2016-11-23 06:27:39
【问题描述】:

我已经检查了几个关于批处理脚本的条件 if 语句语法的资源,尽管如此,我还是找不到我的错误。我通常避免在这里问应该这么简单的问题,但这是一个巨大项目的最后一项任务,所以我希望有人能帮助我看看我做错了什么。这是一个大学项目的脚本,仅用于概念探索。

@Echo OFF

REM Check time remaining
for /f "tokens=3 delims=: " %%a in (
'cscript //nologo "%systemroot%\system32\slmgr.vbs" /dli ^| find "Time remaining: "' 
) do set "timeRemainingStatus=%%a"

Echo %timeRemainingStatus%
pause

REM Check SkipRearm dword value
setlocal ENABLEEXTENSIONS
set KEY_NAME="HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SoftwareProtectionPlatform"
set VALUE_NAME=SkipRearm

FOR /F "usebackq skip=2 tokens=1-3" %%A IN (`REG QUERY %KEY_NAME% /v %VALUE_NAME% 2^>nul`) DO (
set ValueName=%%A
set ValueType=%%B
set ValueValue=%%C
)

Echo Value Name: %ValueName%
Echo Value Value: %ValueValue%
pause

IF %timeRemainingStatus% EQU 20160 (
Echo First level
pause
IF defined ValueName (
    Echo Second Level
    pause
    IF %ValueValue% == "0x0" (
        Echo Third Level
        pause
        regedit.exe /s "C:\Windows\SR.reg"
    )
) ELSE (
    Echo Fourth Level
    pause
    SLMGR /REARM
    )
)
pause

我有回声和暂停,所以我可以看到运行的代码并验证变量是否保留了它们的值。它在第二次暂停后(在 Echo Value Value: %ValueValue% 命令之后)为我崩溃。我认为它的语法有问题,但我无法看到任何错误,因为命令提示符关闭,尽管我有所有的暂停。

【问题讨论】:

  • 您是否尝试将其更改为以下内容? IF "x%timeRemainingStatus%"=="x20160"
  • 感谢您的回复。 x 是做什么的?如果我正确理解了您的其余建议,您建议我进行字符串比较而不是整数比较?将来这个脚本可能必须检查等于或小于 0 的值,我不确定如何通过字符串比较来做这样的事情。
  • x 是为了有一个安全的字符。在进行字符串比较时,我总是建议按照他的方式进行。如果你有一个?,这可能会使你的脚本崩溃。如果您需要整数比较,我建议在您的 if 语句 set /a timeRemainingStatus=%timeRemainingStatus% 之前执行此操作,如果您知道 Java 的工作方式类似于对整数的解析,那么它可以用作那样。如果您没有收到任何错误消息,请按住 shift 并右键单击批处理文件目录,然后单击“在此处打开命令窗口”(类似那样)并键入文件名。窗口不会关闭。
  • x 在引用比较值的情况下完全没用; (an) 额外的字符用于避免空值,这将导致if 子句失败;如果有引号,它们实际上是比较的一部分,因此if 没有任何内容是空的;引号具有额外的优点,即要比较的字符串中的 空格 不再有害。如果您要比较 整数,请不要使用引号(或任何其他额外字符),并使用比较运算符 EQUNEQ 等,而不是 ==,因为如果提供整数,它们会进行数字比较...

标签: batch-file if-statement syntax conditional


【解决方案1】:

有一些地方出错了。这是我采用的解决方案:

@Echo OFF

REM Check time remaining
for /f "tokens=3 delims=: " %%a in (
'cscript //nologo "%systemroot%\system32\slmgr.vbs" /dli ^| find "Time remaining: "' 
) do set /a "timeRemainingStatus=%%a"

setlocal ENABLEEXTENSIONS
set KEY_NAME="HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SoftwareProtectionPlatform"
set VALUE_NAME=SkipRearm

FOR /F "usebackq skip=2 tokens=1-3" %%A IN (`REG QUERY %KEY_NAME% /v %VALUE_NAME% 2^>nul`) DO (
set ValueName=%%A
set ValueType=%%B
set ValueValue=%%C
)

IF %timeRemainingStatus% EQU 0 (
    IF defined ValueName (
        IF "%ValueValue%" == "0x0" (
            regedit.exe /s "C:\Windows\SR.reg"
        )
        IF "%ValueValue%" == "0x1" (
            SLMGR /REARM
        )
    )
)

我需要添加 /a 来设置(我之前以为我有,但我想没有)。此外,在将 %ValueValue% 与“0x0”进行比较时,我忘记了引号。虽然它可能不是最干净的做事方式,但我还将 if-else 更改为两个 if 语句。

我在虚拟机上启动时对此进行了测试,它似乎工作正常。非常感谢所提供的帮助。

【讨论】:

    【解决方案2】:

    在 for 循环或 if 语句中设置变量时,您需要利用 Setlocal EnableDelayedExpansion。这也适用于引用在此上下文中设置的变量。任何使用 EnableDelayedExpansion 的变量都需要在变量周围使用感叹号而不是百分比(!Value! 而不是 %Value%)。您需要更改代码才能利用此功能。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-11
      • 1970-01-01
      • 1970-01-01
      • 2012-03-09
      • 2018-02-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多