For a good solution see the part improved version
You can stop a batch at any point, also inside of nested function calls.
You only need to create a syntax error, for example with an empty block ()
, to suppress the error message, it can be executed in a call, and the stderr of the call is redirected to nul.
@echo off
setlocal enabledelayedexpansion
rem Do something
call :interactive_check
rem Do something
call :interactive_check
goto :eof
::::::::::::::::::::::::::
:interactive_check
if errorlevel 1 (
echo.
echo /!/!/!/!/!/!/!/!/!/!/!/!/!
echo Error in compilation process... exiting
echo /!/!/!/!/!/!/!/!/!/!/!/!/!
call :halt 1
) ELSE (
echo.Continuing to next step
)
goto :eof
:: Sets the errorlevel and stops the batch immediately
:halt
call :__SetErrorLevel %1
call :__ErrorExit 2> nul
goto :eof
:__ErrorExit
rem Creates a syntax error, stops immediately
()
goto :eof
:__SetErrorLevel
exit /b %time:~-2%
goto :eof
2017-04-09 Improved version: Exit only the current batch, but not the caller batch
As @dbenham mentioned, there is a new technic for exception handling that can also be used for exiting only the current batch.
@echo off
echo Do something, detecting some fatal error
call :ExitBatch 3
exit /b
:ExitBatch [errorcode] - Exits only the current batch file, regardless how many CALLs
set _errLevel=%1
REM *** Remove all calls from the current batch from the call stack
:popStack
(
(goto) 2>nul
setlocal DisableDelayedExpansion
call set "caller=%%~0"
call set _caller=%%caller:~0,1%%
call set _caller=%%_caller::=%%
if not defined _caller (
REM callType = func
rem set _errLevel=%_errLevel%
goto :popStack
)
(goto) 2>nul
endlocal
cmd /c "exit /b %_errLevel%"
)
echo NEVER REACHED
exit /b
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…