Использование фатальной синтаксической ошибки, как демонстрирует jeb, убивает всю пакетную обработку, но также имеет неприятный побочный эффект - изменения среды после SETLOCAL сохраняются, даже если предполагается, что они будут отброшены через неявный ENDLOCAL, когда пакетная обработка завершится,См. Мой пост DosTips SETLOCAL продолжается после завершения пакета! для получения дополнительной информации.
Основано на информации в Почему неинтерактивный пакетный скрипт считает, что я нажал control-C?, я обнаружил чистый способ выхода из всех пакетных сценариев из подпрограммы или сценария CALLed, и все изменения после SETLOCAL должным образом отбрасываются.
@echo off
setlocal
set test=AFTER main SETLOCAL
call :sub
echo returning from main NEVER REACHED
exit /b
:sub
setlocal
set test=AFTER sub SETLOCAL
set test
call :ExitBatch
echo returning from sub2 NEVER REACHED
exit /b
:ExitBatch - Cleanly exit batch processing, regardless how many CALLs
if not exist "%temp%\ExitBatchYes.txt" call :buildYes
call :CtrlC <"%temp%\ExitBatchYes.txt" 1>nul 2>&1
:CtrlC
cmd /c exit -1073741510
:buildYes - Establish a Yes file for the language used by the OS
pushd "%temp%"
set "yes="
copy nul ExitBatchYes.txt >nul
for /f "delims=(/ tokens=2" %%Y in (
'"copy /-y nul ExitBatchYes.txt <nul"'
) do if not defined yes set "yes=%%Y"
echo %yes%>ExitBatchYes.txt
popd
exit /b
Вот пример выходных данных запуска вышеуказанного теста.летучая мышь.Вы можете видеть, что скрипт никогда не возвращался из вызова: ExitBatch, и определение тестовой переменной было правильно отброшено после завершения пакетной обработки.
C:\test>test.bat
test=AFTER sub SETLOCAL
C:\test>set test
Environment variable test not defined
C:\test>
Процедура: ExitBatch может быть помещена в ее собственный файл ExitBatch.batсценария и помещен где-то в пределах вашей переменной PATH, так что он может быть удобно использован любым пакетным сценарием.
@echo off
:ExitBatch - Cleanly exit batch processing, regardless how many CALLs
if not exist "%temp%\ExitBatchYes.txt" call :buildYes
call :CtrlC <"%temp%\ExitBatchYes.txt" 1>nul 2>&1
:CtrlC
cmd /c exit -1073741510
:buildYes - Establish a Yes file for the language used by the OS
pushd "%temp%"
set "yes="
copy nul ExitBatchYes.txt >nul
for /f "delims=(/ tokens=2" %%Y in (
'"copy /-y nul ExitBatchYes.txt <nul"'
) do if not defined yes set "yes=%%Y"
echo %yes%>ExitBatchYes.txt
popd
exit /b
Важное обновление:
Теперь можно реализовать надежныйобработка исключений с чистой партией.Вы можете не только выбросить исключение, которое может прекратить всю пакетную обработку с любого уровня CALL, но вы также можете перехватить исключение на более высоком уровне, исключить специальный код обработки для обработки исключений и возобновить обработку, или продолжить выход через другой выброс!См. Поддерживает ли пакетная обработка Windows обработку исключений? для получения дополнительной информации.