Usando un error de sintaxis fatal, como demuestra Jeb, mata todo el procesamiento por lotes, pero también tiene un efecto secundario desagradable - cambios en el entorno después de SETLOCAL se conservan, a pesar de que se supone que deben ser desechados a través de ENDLOCAL implícita cuando termina el procesamiento por lotes Vea mi publicación DosTips SETLOCAL continues after batch termination! para más información.
Basado en información en Why does a non-interactive batch script think I've pressed control-C?, he descubierto una manera limpia de salir de todas las secuencias de comandos por lotes desde una rutina LLAMADA o secuencia de comandos, y todos los cambios después de SETLOCAL se descartan correctamente.
@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
Aquí se muestra el resultado de ejecutar el test.bat anterior. Puede ver que la secuencia de comandos nunca volvió de la llamada ExitBatch y la definición de la variable de prueba se ha descartado correctamente una vez que finaliza el procesamiento por lotes.
C:\test>test.bat
test=AFTER sub SETLOCAL
C:\test>set test
Environment variable test not defined
C:\test>
La rutina ExitBatch se puede poner en su propio ExitBatch.bat script y colocado en algún lugar dentro de tu PATH de modo que pueda ser usado convenientemente por cualquier secuencia de comandos por lotes.
@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
Actualización importante:
Ahora es posible implementar el manejo de lotes con excepción puro robusto. No solo puede lanzar una excepción que puede finalizar todo el procesamiento por lotes desde cualquier nivel CALL, sino que también puede detectar la excepción en un nivel superior, superar el código especial de limpieza de manejo de excepciones y reanudar el procesamiento, o continuar saliendo por otro lanzamiento. Ver Does Windows batch support exception handling? para más información.
No se puede. Simplemente reemplace 'call: interactive_check' con' if errorlevel 1 goto error'. No hay mucha diferencia entre copiar y pegar ex o último. :) – atzz
Lo tengo, resolvió el problema con esto y funciona bien, ¡gracias! – Gui13