Warum wird der Wert von ErrorLevel nicht aktualisiert?

2062
PsychoData

Ich versuche, eine Subroutine im Stapel zu schreiben, um festzustellen, ob auf einem Computer Deep Freeze installiert ist oder ob er gefroren ist. (Für diejenigen, die es nicht wissen, ist Deep Freeze ein Programm, das häufig zum Rückgängigmachen / Verhindern und Ändern von Festplatten in einem Betriebssystem verwendet wird.) Dfc.exe ist eine Datei, die mit Deep Freeze installiert wird und zur Bestimmung verwendet werden kann. Es gibt 0 zurück, wenn es aufgetaut ist, oder 1, wenn es eingefroren ist

Im Grunde dachte ich, dass es sinnlos ist, Skripts auszuführen, die bestimmte Dinge installieren, wenn der Computer eingefroren ist. Zuerst überprüfe ich, ob die Datei dfc.exe installiert ist. Dann versuche ich, den Status "Aufgetaut / Gefroren" zu überprüfen. Das Problem ist jedoch, dass der Rückgabewert der Datei "dfc" aus irgendeinem Grund nicht zu aktualisieren scheint.

Jeder weiß, warum ich den Rückgabewert der zweiten ErrorLevel-Prüfung ( in Zeile 41 ) nicht sehen kann. Ich habe den folgenden Code ebenfalls hinzugefügt .

BEARBEITEN: Psuedocode für meinen Denkprozess vor dem Code hinzugefügt.

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

@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: Ich gab die verschachtelten IFs auf und ging zurück zu GOTOs und Labels. Es ist nicht so hübsch, aber dieser Code funktioniert tatsächlich und in buchstäblich zehn Minuten. Ich habe es eingerückt, um den visuellen Effekt der künstlichen "Verschachtelung" zu erzeugen

@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
Versuchen Sie es mit 'errorlevel 1', anstatt die Umgebungserweiterung zu verwenden. Pablo Montilla vor 9 Jahren 0
"IF errorlevel 0" sagt "Die Syntax des Befehls ist falsch" und stürzt das Skript ab. Insbesondere habe ich die IF ersetzt, die prüft, ob eine Datei zwischen den Punkten Point1 und Point2 gefunden wurde. (Ich habe auch das andere ersetzt, aber das Skript ist abgestürzt, bevor es dort ankam.) PsychoData vor 9 Jahren 0
Ich denke, die Syntax `if errorlevel n` wird übergeben, wenn errorlevel größer oder gleich n ist. "If errorlevel 0" macht also keinen Sinn, aber für den Teil, der die Überprüfung von "if errorlevel 1" durchführt, sollte es funktionieren. Pablo Montilla vor 9 Jahren 1
@PabloMontilla ahh, eine Nuance, die ich vermisst habe. Einen Moment. PsychoData vor 9 Jahren 0
Ich denke, dass es den Fehlerlevel 0 nicht mochte, ich ging zurück zu der Art, wie ich es überprüft hatte. Es sieht so aus, als würde man den Fehlerlevel überprüfen, dass (Ihr) Weg seltsame Dinge auf der Linie macht. http://snag.gy/dpXHr.jpg PsychoData vor 9 Jahren 0

4 Antworten auf die Frage

2
Tyler

ERRORLEVEL aktualisiert keine Steuerblöcke wie IF-Anweisungen, es sei denn, Sie verwenden! ERRORLEVEL! Verwenden Sie anstelle von% ERRORLEVEL% diesen Befehl zu Beginn Ihres Codes: setlocal ENABLEDELAYEDEXPANSION

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

0
SadBunny

Ihr Problem ist, dass Ihre zweite Prüfung INNERHALB des Codeblocks ist, der NUR verwendet wird, wenn Ihre erste Prüfung gleich 0 ist.

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

Die zweite Prüfung, ob es regnet, wird durchgeführt, und NUR, wenn wir ausgehen möchten. Wenn wir nicht ausgehen wollen, kümmern wir uns nicht um Regen.

Lösung: Schließen Sie den Block nach Ihrer ersten IF, bevor Sie zur zweiten kommen, wenn:

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

Oder verwenden Sie eine ELSE:

IF %ERRORLEVEL% EQU 0 ( do stuff ) ELSE ( :: errorlevel was anything other than 0, i.e. NEQ 0 do other stuff ) 
Ihre Antwort ist großartig und alles, aber ich denke, Sie missverstehen ein wenig. Ich habe psuedocode hinzugefügt, um meinen allgemeinen Denkprozess ohne all das Übermaß zu erklären. Grundsätzlich möchte ich bei Punkt2 den DFC-Befehl ausführen und dann bei Punkt3 ein paar Befehle ausführen. Wenn es nicht eingefroren ist, würde es die IF überspringen und es auf P4 bringen. Hier wird nichts ausgeführt, und es würde die innere IF beenden und es bis P5 schaffen. Bei P5 kehren wir kurz dorthin zurück, wo wir zuerst abgereist sind. PsychoData vor 9 Jahren 0
... Nist ich die IFs falsch oder etwas? PsychoData vor 9 Jahren 0
Hmmz, ich scheine in der Tat falsch verstanden zu werden. Also ... Ihr Problem ist, dass die Zeile "ECHO% errorlevel%" immer 0 oder immer 1 zurückgibt, auch wenn dies nicht der Fall ist? Was gibt es immer zurück? SadBunny vor 9 Jahren 0
Mein errorlevel muss immer Null sein, wenn ich die erste IF eingebe und Point2 erreicht habe. Danach würde dfc.exe ausgeführt werden. Wenn der Computer eingefroren ist, würde der errorlevel auf 1 geändert (wie ich die Dinge verstehe), aber egal was ich sehe das nie. Ich habe sogar versucht, die Zeile zu ändern, die dfc get / ISFROZEN aufruft, um eine temporäre bat-Datei aufzurufen, die den Errorlevel in etwas wie 1231234 ändert, nur um zu sehen, ob ich sie sehen würde. immer noch nicht PsychoData vor 9 Jahren 0
0
wallyk

Ich habe keine leicht zugängliche Windows-Maschine, aber wenn ich es wäre, würde ich überprüfen, dass sich die ECHOAussage nicht ändert ERRORLEVEL.

Wahrscheinlich ist dies nicht verwandt, aber vielleicht verwenden Sie einen Befehlsinterpreter, der Groß- und Kleinschreibung ERRORLEVELunterschiedlich behandelt. Selbst wenn dies keine Auswirkung hat, ist es eigenartig, inkonsistent zu sein.

Der Groß- / Kleinschreibfehler macht keinen Unterschied. Es ist zwar sauberer für mich, aber ich werde mich nicht darum kümmern, das in der Frage zu bearbeiten, nur in meiner Kopie. Normalerweise bekomme ich alles zum Laufen und mache es dann schön. PsychoData vor 9 Jahren 0
Ich denke, das Echo bleibt beim Ändern des Fehlerpegels bestehen und bleibt, was es zuvor war. Wenn Sie über die Zeile sprechen, in der ich gerade den Fehlerlevel anzeigt, hatte ich das gleiche Problem und habe es nur zur Fehlerbehebung eingefügt. http://stackoverflow.com/questions/20770788/why-the-return-value-of-echo-is-always-1 PsychoData vor 9 Jahren 0
Ich habe es versucht; Das Echo scheint den Fehler nicht zu ändern. SadBunny vor 9 Jahren 0
0
JonathanDavidArndt

Die folgende Batchdatei gibt Ihnen den Status, nach dem Sie suchen. Sie können die gotosEtiketten und leicht an Ihre Bedürfnisse anpassen .

Ob die Datei existiert, wird geprüft und ERRORLEVELentsprechend aktualisiert.

@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