Уровень ошибки пакетного файла установлен на 0 при запуске

Уровень ошибки при запуске файла .bat равен 0. Однако я использую уровень ошибки как условие, например:

REG Query HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall\test 2>NUL>>MMG.dat
If %ERRORLEVEL% == 0 goto turnon

REG Query HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall\test2>NUL>>MMG.dat
If %ERRORLEVEL% == 0 goto turnon

REG Query HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall\test 3>NUL>>MMG.dat
If %ERRORLEVEL% == 0 goto turnon
If %ERRORLEVEL% == 1 goto EOF

Моя проблема в том, что если уровень ошибки уже установлен на 0, то условие становится недействительным.

В любом случае, я могу обойти это?

Примечание: уровень ошибки НЕ установлен нигде в файле.

Я изучаю этот язык, поэтому, пожалуйста, потерпите меня, если это очевидная ошибка.

Спасибо


person DaE    schedule 11.12.2013    source источник
comment
Что вы имеете в виду, если уровень ошибки уже установлен на 0? Вы имеете в виду, что установлена ​​переменная среды с именем ERRORLEVEL? (Вы можете проверить, используя команду set, чтобы получить список всех переменных среды.) В противном случае у вас нет проблемы, потому что любой предыдущий уровень ошибки забывается, как только вы запускаете новую команду.   -  person Harry Johnston    schedule 11.12.2013
comment
Переменные уровня ошибок среды не установлены. Когда я запускаю сценарий, уровень ошибки уже равен 0 (я добавляю echo ERRORLEVEL IS: %errorlevel% в самом верху сценария, чтобы показать уровень ошибки). Проблема в том, что я использую уровень ошибки в качестве условия (см. пример выше), и если уровень ошибки уже равен 0, то это условие становится недействительным с точки зрения сценариев. У меня есть несколько запросов reg с условием if под каждым, и если значение reg существует (уровень ошибки 0), предупредите пользователя с помощью команды goto.   -  person DaE    schedule 11.12.2013
comment
Неважно, какой уровень ошибки уже есть. Каждый раз, когда вы запускаете команду reg, уровень ошибки меняется, поэтому при тестировании %ERRORLEVEL% вы получаете только результат предыдущей команды.   -  person Harry Johnston    schedule 11.12.2013
comment
Следуя из этого комментария - некоторые программы и команды не выставляют уровень ошибки, поэтому надо проверять используемую программу. REG устанавливает уровень ошибок, поэтому ваш код будет работать нормально.   -  person foxidrive    schedule 11.12.2013
comment
@foxidrive: правда. В этом контексте следует отметить, что то, устанавливает ли программа уровень ошибки, зависит только от того, является ли она исполняемым файлом с графическим интерфейсом или командной строкой, поэтому программа не может иногда устанавливать уровень ошибки, а иногда нет. (Является ли возвращаемый уровень ошибки осмысленным — это совсем другой вопрос!) Внутренние команды в принципе могут устанавливать уровень ошибки только при некоторых условиях, но, насколько я знаю, таких случаев не бывает; каждая внутренняя команда либо всегда, либо никогда не устанавливает уровень ошибки.   -  person Harry Johnston    schedule 11.12.2013


Ответы (1)


Кажется, я припоминаю, что использовать саму переменную %errorlevel% - плохая идея по целому ряду причин, в том числе из-за того, что ее можно установить вручную, что отключает ее от фактических кодов возврата. Для получения более подробной информации см. эту статью на страницах сценариев Роба ван дер Вуда, ценный ресурс по всем вопросам скрипты под Windows/DOS.

Вы должны использовать что-то вроде:

if errorlevel 1 ...

Однако я не полностью уверен, что вы считаете здесь неправильным. Да, %errorlevel% может быть установлено равным нулю перед запуском скрипта, но это будет изменено при первом вызове reg, который установит его в 0 в случае успеха или 1 в случае неудачи.

Если вы хотите что-то сделать в случае сбоя reg query, просто используйте:

reg query 1 blah blah blah
if errorlevel 1 goto turnon

reg query 2 yak yak yak
if errorlevel 1 goto turnon

reg query 1 bjork brork bjork
if errorlevel 1 goto turnon

Если это что-то делать (например, предупреждать о любых сбоях в соответствии с вашим вопросом/комментарием), то то, что у вас есть, в порядке, просто с немного другим методом и значением:

set bad=0

reg query 1 blah blah blah
if errorlevel 1 goto alert

reg query 2 yak yak yak
if errorlevel 1 goto alert

reg query 1 bjork brork bjork
if errorlevel 1 goto alert

rem all queries returned success.
person paxdiablo    schedule 11.12.2013
comment
Извините, если я ошибаюсь, но если значение reg найдено, уровень ошибки должен быть равен 0 и, следовательно, перейти к включению. Однако, если уровень ошибки уже установлен на 0, а значение reg не существует и выполняется условие (если), то он все равно включится, поскольку уровень ошибки равен 0. - person DaE; 11.12.2013
comment
@DaE: нет, если исполняемый файл reg не найдет ключ, он установит уровень ошибки 1. Попробуйте с reg query hkey_current_user и reg query hkey_nosuch_user после каждого с echo %errorlevel%. - person paxdiablo; 11.12.2013
comment
Спасибо за вашу помощь в этом. Оператор if фактически предназначен для предупреждения, если значение найдено, например. code REG Query HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall\test 2>NUL>>MMG.dat If %ERRORLEVEL% == 0 goto alert REG Query HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall\test2>NUL>>MMG.dat If %ERRORLEVEL% == 0 goto alert REG Query HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall\test 3>NUL>>MMG.dat If %ERRORLEVEL% == 0 goto alert If %ERRORLEVEL% == 1 goto EOF Таким образом, идеальным результатом было бы, если бы значение не было найдено - person DaE; 11.12.2013
comment
@DoE, тогда вам нужен код в соответствии с моим вторым образцом, я изменю его в соответствии с вашим комментарием. - person paxdiablo; 11.12.2013
comment
FWIW, я не согласен с тем, что вы не должны использовать %ERRORLEVEL%. Да, он ломается, если кто-то устанавливает переменную окружения с таким же именем, на что очевидный ответ: не делайте этого. Команда if errorlevel имеет более серьезную проблему, поскольку она обрабатывает уровень ошибки как значение со знаком, поэтому неправильно ведет себя для уровней ошибок выше 2^31. (Они более распространены, чем вы думаете.) - person Harry Johnston; 11.12.2013
comment
Если я использую нижний сценарий, который вы дали, сценарий выполнит первую команду, и если ничего не будет найдено, он перейдет к no_alert без выполнения других запросов? Мне нужно выполнить все запросы, однако, если одно значение будет найдено предупреждение. - person DaE; 11.12.2013
comment
@DaE, тогда в вашем вопросе была правильная идея, просто с неправильными значениями. Смотрите мое обновление ко второму фрагменту. - person paxdiablo; 11.12.2013
comment
Спасибо за вашу помощь. Посмотрю на реструктуризацию моего командного файла. - person DaE; 11.12.2013