1

Я пытаюсь написать подпрограмму в пакетном режиме, чтобы определить, установлен ли на компьютере режим Deep Freeze или он надежно заморожен. (Для тех, кто не знает, Deep Freeze - это программа, которая обычно используется для восстановления / предотвращения и изменения диска в операционной системе.) Dfc.exe - это файл, который можно установить при помощи глубокой заморозки. Возвращает 0 в случае размораживания или 1 в случае замораживания

По сути, я думал, что бессмысленно запускать скрипты, которые устанавливают определенные вещи, если компьютер завис. Сначала я проверяю, установлен ли dfc.exe, затем я пытаюсь проверить, не оттаяло ли оно, но проблема в том, что по какой-то причине возвращаемое значение dfc не обновляется, когда я проверяю уровень ошибки во второй раз.

Кто-нибудь знает, почему я не вижу возвращаемого значения второй проверки ErrorLevel (в строке 41), которую я также включил в код ниже.

РЕДАКТИРОВАТЬ: Добавлен Psuedocode для моего мыслительного процесса перед кодом.

::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 и вернулся к GOTOs и Labels. Это не так красиво, но этот код на самом деле работает и буквально за десять минут. Я отступил, чтобы создать визуальный эффект искусственного "вложения"

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

4 ответа4

2

ERRORLEVEL не обновляет внутренние блоки управления, такие как операторы IF, если вы не используете!ERRORLEVEL! вместо% ERRORLEVEL% и используйте эту команду в начале вашего кода: setlocal ENABLEDELAYEDEXPANSION

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

0

Следующий пакетный файл даст вам статус, который вы ищете. Вы можете легко настроить 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
0

Ваша проблема в том, что ваша вторая проверка выполняется в блоке кода, который используется ТОЛЬКО, если ваша первая проверка равна 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
)
0

У меня нет легко доступного компьютера с Windows, но на моем месте я бы проверил, что оператор ECHO не меняет ERRORLEVEL .

Возможно, это не связано, но, возможно, вы используете интерпретатор команд, который по-разному обрабатывает прописные и строчные буквы ERRORLEVEL ? Даже если это не имеет никакого эффекта, это свойственно быть непоследовательным.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .