1

I am trying to write a subroutine in batch to determine if a computer has Deep freeze installed or is safely unfrozen. (For those who don't know, Deep Freeze is a program that is commonly used to revert/prevent and disk changes in an Operating System.) dfc.exe is a file that deep freeze installs that can be used to determine. It returns 0 if thawed, or 1 if frozen

Basically, I was thinking that it's pointless to run scripts that install certain things if the computer is frozen. First I check for if dfc.exe is installed, then I attempt to check for thawed/frozen state but the problem IS that for some reason the return value of the dfc doesn't seem to update for where I check errorlevel the second time.

Anyone know why I can't see the return value of the second ErrorLevel check (on line 41) I've included the code below as well.

EDIT: Added Psuedocode for my thought process before the code.

::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) 

Code below here

@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

UPDATE: I gave up on the nested IFs and went back to GOTOs and Labels. It's not as pretty, but this code actually WORKS and in literally like ten minutes. I indented it to create the visual effect of the artificial "nesting"

@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)
PsychoData
  • 1,397
  • 1
  • 13
  • 38
  • Try checking with 'errorlevel 1' instead of using de environment expansion. – Pablo Montilla Jan 17 '15 at 15:02
  • `IF errorlevel 0` says `The Syntax of the Command is Incorrect` and crashes the script. Specifically I replaced the IF that checks whether a file was found between points Point1 and Point2. (I replaced the other one as well, but the script crashed before it got there) – PsychoData Jan 17 '15 at 15:54
  • 1
    I think the syntax `if errorlevel n` passes when errorlevel is greater or equal to n. So `if errorlevel 0` doesn't make sense, but for the part that does the checking `if errorlevel 1` should work. – Pablo Montilla Jan 17 '15 at 15:58
  • @PabloMontilla ahh, a nuance that I missed. One moment. – PsychoData Jan 17 '15 at 15:58
  • I think that it didn't like the errorlevel 0, I went back to the way I had been checking it. It looks like checkinmg the errorlevel that (your) way does weird things on the line. http://snag.gy/dpXHr.jpg – PsychoData Jan 17 '15 at 16:08

4 Answers4

4

ERRORLEVEL doesn't update inside control blocks like IF statements unless you use !ERRORLEVEL! instead of %ERRORLEVEL% and use this command at the start of your code: setlocal ENABLEDELAYEDEXPANSION

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

Tyler
  • 41
  • 2
0

The following batch file will give you the status that you are looking for. You can easily adjust the gotos and labels to suit your needs.

Whether the file exists is checked, and ERRORLEVEL is updated appropriately.

@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
JonathanDavidArndt
  • 1,344
  • 7
  • 25
  • 42
0

Your problem is that your second check is WITHIN the block of code that is used ONLY if your first check equals 0. You're like:

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

See, the second check to see whether it rains is performed if, and ONLY if, we want to go out. If we don't want to go out, we don't bother checking for rain.

Solution: close the block after your first IF before you get to the second if, so you get:

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

Or use an ELSE:

IF %ERRORLEVEL% EQU 0 (
  do stuff
)
ELSE (
  :: errorlevel was anything other than 0, i.e. NEQ 0
  do other stuff
)
SadBunny
  • 1,416
  • 2
  • 12
  • 15
  • So, your answer is great and all, but I think you're misunderstanding a little. I've added psuedocode to explain my general thought process without all the excess. Basically at Point2 I want to run the DFC command and Then at Point3 I need to run a couple commands. If it is not frozen, it would skip that IF and make it to P4. Nothing is executed here and it would finish the inner IF and make it to P5. At P5, we return to just after where we left in the first place. – PsychoData Jan 17 '15 at 04:59
  • ...Am I nesting the IFs wrong or something? – PsychoData Jan 17 '15 at 05:04
  • Hmmz, seems I misunderstood indeed. So... Your problem is that the line "ECHO %errorlevel%" always returns 0 or always returns 1, even when it shouldn't? What does it always return? – SadBunny Jan 17 '15 at 05:39
  • My errorlevel always has to be zero when I enter the first IF and reach Point2, after that dfc.exe would execute and ,if the computer is frozen, errorlevel would change to 1 (as I understand things) but, no matter what, I never see that. I've even tried changing the line that calls dfc get /ISFROZEN to call a temporary bat file that would change errorlevel to something like 1231234 just to see if I would see it. still didn't – PsychoData Jan 17 '15 at 15:49
0

I don't have a windows machine easily available, but if it were me, I would verify that the ECHO statement does not change ERRORLEVEL.

Probably this is not related, but maybe you are using a command interpreter which treats uppercase and lowercase ERRORLEVEL differently? Even if that has no effect, it is peculiar to be inconsistent.

wallyk
  • 1,348
  • 10
  • 18
  • Upper/Lowercase errorlevel makes no difference. It is cleaner for me to fix it though, I won't bother editing that in the question though, just my copy. I usually kind of get everything working and then make it pretty. – PsychoData Jan 17 '15 at 05:12
  • Reguarding the echo changing the errorlevel, I think that it stays whatever it was before. If you're talking about the line where I just display the errorlevel, I was having the same problem before and I just put it in there for troubleshooting. http://stackoverflow.com/questions/20770788/why-the-return-value-of-echo-is-always-1 – PsychoData Jan 17 '15 at 05:21
  • Tried it; echo doesn't seem to change errorlevel. – SadBunny Jan 17 '15 at 05:43