为什么 ErrorLevel 的值没有更新?

为什么 ErrorLevel 的值没有更新?

我正在尝试批量编写一个子程序来确定计算机是否安装了 Deep Freeze 或是否安全解冻。(对于那些不知道的人来说,深度冻结是一个常用于在操作系统中恢复/阻止和磁盘更改的程序。执行程序是 Deep Freeze 安装的一个文件,可用于确定。如果已解冻,则返回 0;如果已冻结,则返回 1

基本上,我认为如果计算机冻结,运行安装某些东西的脚本是没有意义的。首先,我检查 dfc.exe 是否已安装,然后尝试检查解冻/冻结状态,但问题是出于某种原因,dfc 的返回值似乎没有在我第二次检查错误级别时更新。

有人知道为什么我看不到第二个 ErrorLevel 检查的返回值(在第 41 行)我还在下面附上了代码。

编辑:在代码之前添加了伪代码来表达我的思考过程。

::Point1
IF Dfc.exe is present then (
    ::Point2
    If "dfc get /ISFROZEN" returns FROZEN then (
        ::Point3
        Write out to file so we can know that something was skipped, 
        goto EOF to close out of script and avoid wasting cycles installing
    )
    ::Point4

::Deep freeze is installed, but thawed or it would have gotten caught in the "FROZEN" IF
::Fall through out of outer IF without running anything else
)
::Point5

GOTO (Return to where we left to check if we were wasting time with a label) 

下面的代码

@ECHO Off
::CheckForDF here
ECHO We will now test for DeepFreeze ether not installed or is thawed
Pause 
ECHO.

set flagfile=C:\testjava.txt
::Flagfile variable should already be defined before calling this function
Goto :CheckForDF
:DFNotFrozen
ECHO DeepFreeze wasn't installed or is currently thawed
ECHO **Continue with the rest of the script** 
ECHO.
PAUSE

GOTO:eof







::***************************
::********Subroutines********
::***************************


:CheckForDF
WHERE dfc >nul 2>&1


::ErrorLEvel 0 means file was found, which means DF is installed

IF %ERRORLEVEL% EQU 0 (
   dfc get /ISFROZEN
   ECHO %errorlevel%
   ::ErrorLevel 0 - THAWED and ready to install 
   ::ErrorLevel 1 - FROZEN and pointless to try

   IF %errorlevel% EQU 1 (

      ::Echo out what WOULD have been installed to a file so we could check that the
      ::   script still ran (and get an idea of how bad we need to unfreeze and log into each computer) 
      ECHO %flagfile% %date%%time% >> C:\BRCCIT\ScriptsSkippedByDeepFreeze.txt
      ECHO ****DeepFreeze is currently frozen****

      ECHO.
      PAUSE   
      ::Else - DeepFreeze is thawed. return to normal script
      goto :EOF

   )

   ::DeepFreeze is thawed, but is installed. We'll just fall through to the not installed result
)

::DeepFreeze Installation not found. Okay to return to normal script
ECHO DeepFreeze is not installed
goto :DFNotFrozen

更新:我放弃了嵌套的 IF,转而使用 GOTO 和标签。虽然不太美观,但这段代码确实有效,而且只用了 10 分钟。我缩进它以创建人工“嵌套”的视觉效果

@ECHO Off
::CheckForDF here
ECHO We will now test for DeepFreeze ether not installed or is thawed
Pause 
ECHO.

set flagfile=C:\testjava.txt
::Flagfile variable should already be defined before calling this function
Goto :CheckForDF
:DFNotFrozen
ECHO DeepFreeze wasn't installed or is currently thawed
ECHO **Continue with the rest of the script** 
ECHO.
PAUSE

GOTO:eof



::***************************
::********Subroutines********
::***************************



:CheckForDF
WHERE dfc >nul 2>&1

IF %ErrorLevel% EQU 0 Goto :DFInstalled
::ELSE - DF Not  found 
GOTO :ReturnToScript


    :DFInstalled
    ::DFC.exe get /ISFROZEN
    Call ExitWithSpecifiedCode.bat 1
    ::If Frozen
    IF %ErrorLevel% EQU 1 GOTO DFFrozen
    ::If Thawed
    IF %ErrorLevel% EQU 0 GOTO ReturnToScript


        :DFFrozen
        ECHO %flagfile% %date%%time% >> C:\BRCCIT\ScriptsSkippedByDeepFreeze.txt
        ECHO ****DeepFreeze is currently frozen****

        ECHO.
        PAUSE
        ::Exit Script Execution
        goto :EOF

:ReturnToScript
ECHO ReturnToScript
PAUSE
GOTO (Return to script execution)

答案1

ERRORLEVEL 不会在 IF 语句等控制块内更新,除非您使用 !ERRORLEVEL! 而不是 %ERRORLEVEL%,并在代码开头使用此命令:setlocal ENABLEDELAYEDEXPANSION

http://batcheero.blogspot.ca/2007/06/how-to-enabledelayedexpansion.html

答案2

您的问题是,您的第二次检查是在仅当您的第一次检查等于 0 时才使用的代码块内。您就像:

IF (we want to go out) THEN (
  IF (it rains) THEN (
    take umbrella
  )
)

瞧,第二次检查是否下雨是在我们想出门时才进行的。如果我们不想出门,我们就不会费心检查是否下雨。

解决方案:在到达第二个 if 之前,关闭第一个 IF 之后的块,因此您得到:

IF %ERRORLEVEL% EQU 0 (
  do stuff
)
IF %errorlevel% EQU 1 (
  do other stuff
)

或者使用 ELSE:

IF %ERRORLEVEL% EQU 0 (
  do stuff
)
ELSE (
  :: errorlevel was anything other than 0, i.e. NEQ 0
  do other stuff
)

答案3

我没有一台可用的 Windows 机器,但如果是我的话,我会验证该ECHO语句不会改变ERRORLEVEL

可能这不相关,但也许你使用的命令解释器对大写和小写ERRORLEVEL有不同的处理方式?即使这没有影响,不一致也是很奇怪的。

答案4

以下批处理文件将为您提供所需的状态。您可以轻松调整gotos和标签以满足您的需要。

检查文件是否存在,并ERRORLEVEL进行适当更新。

@echo off

REM ---------------------------------------------------------------------------------
REM -- Check the status of Deep Freeze
set "DFC=C:\Program Files (x86)\Faronics\Deep Freeze Enterprise\DFC.exe"
if not exist "%DFC%" goto alwaysRun
"%DFC%" get /ISFROZEN >nul 2>&1
if [9009] == [%ERRORLEVEL%] goto alwaysRun
if ERRORLEVEL 1 goto isFrozen
if ERRORLEVEL 0 goto isThawed
REM ---------------------------------------------------------------------------------





REM ---------------------------------------------------------------------------------
REM -- Run all the commands when the workstation is frozen
REM -- (these commands are skipped when the workstation is thawed)
goto alwaysRun
:isFrozen

echo The workstation is frozen
REM ---------------------------------------------------------------------------------





REM ---------------------------------------------------------------------------------
REM -- Run all the commands when the workstation is thawed
REM -- (these commands are skipped when the workstation is frozen)
goto alwaysRun
:isThawed

echo The workstation is thawed
REM ---------------------------------------------------------------------------------





REM ---------------------------------------------------------------------------------
:alwaysRun

echo Always run this part
REM ---------------------------------------------------------------------------------





REM ---------------------------------------------------------------------------------
:end
pause

相关内容