jeb的致命语法错误方法可以使用,但它不能正确终止任何活动的SETLOCAL。
例如,这是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
以下是演示运行输出,证明测试仍然被定义并且批处理终止后可启用延迟扩展:
C:\test>fatalTest
test=AFTER sub SETLOCAL
C:\test>echo !test!
AFTER sub SETLOCAL
C:\test>
现在已经不可能将环境恢复到批处理之前的状态。CMD.EXE会话应该被终止。
这是一个改进后的CtrlCTest.bat版本,它可以在批处理结束时正确地终止任何活动的SETLOCAL。它使用了一种令人惊讶的技术来编程"按下"Ctrl-C,我在为什么非交互式批处理脚本认为我按下了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
以下是示例运行输出。您可以看到延迟扩展不再处于活动状态,test也不再被定义:
C:\test>CtrlCTest
test=AFTER sub SETLOCAL
C:\test>echo !test!
!test!
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
:HALT
,在XP系统中直接调用:__halt 2>nul
即可,没有错误信息。 - Endoro