jeb's fatal syntax error method works, but it does not properly terminate any active SETLOCAL.
For example, here is fatalTest.bat:
@echo off
setlocal enableDelayedExpansion
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
call :__exitBatch 2>nul
:__ExitBatch
for
And here is sample run output demonstrating how test is still defined and delayed expansion is still enabled after batch processing terminates:
C:\test>fatalTest
test=AFTER sub SETLOCAL
C:\test>echo !test!
AFTER sub SETLOCAL
C:\test>
It is now impossible to restore the environment to a pre-batch state. The CMD.EXE session should be terminated.
Here is an improved CtrlCTest.bat version that properly terminates any active SETLOCAL upon batch termination. It uses a surprising technique to programmatically "press" Ctrl-C that I learned about at Why does a non-interactive batch script think I've pressed control-C?
@echo off
setlocal enableDelayedExpansion
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
And here is sample run output. You can see that delayed expansion is no longer active, and test is no longer defined:
C:\test>CtrlCTest
test=AFTER sub SETLOCAL
C:\test>echo !test!
!test!
C:\test>set test
Environment variable test not defined
C:\test>
You could put the :ExitBatch routine in a stand-alone ExitBatch.bat script that resides somewhere within your PATH, and then any batch can conveniently CALL the utility as needed.
@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