How can I exit a batch file from within a function?

Brad Conyers picture Brad Conyers · May 10, 2012 · Viewed 57.4k times · Source

I have a simple function written to check for directories:

:direxist
if not exist %~1 (
    echo %~1 could not be found, check to make sure your location is correct.
    goto:end
    ) else (
    echo %~1 is a real directory
    goto:eof
    )

:end is written as

:end
endlocal

I don't understand why the program would not stop after goto:end has been called. I have another function that uses the same method to stop the program and it work fine.

:PRINT_USAGE
echo Usage:
echo ------
echo <file usage information>
goto:end

In this instance, the program is stopped after calling :end; why would this not work in :direxist? Thank you for your help!

Answer

jeb picture jeb · May 10, 2012

I suppose you are mixing call and goto statements here.

A label in a batch file can be used with a call or a goto, but the behaviour is different.
If you call such a function it will return when the function reached the end of the file or an explicit exit /b or goto :eof (like your goto :end).

Therefore you can't cancel your batch if you use a label as a function.

However, goto to a label, will not return to the caller.

Using a synatx error:

But there is also a way to exit the batch from a function.
You can create a syntax error, this forces the batch to stop.
But it has the side effect, that the local (setlocal) variables will not be removed.

@echo off
call :label hello
call :label stop
echo Never returns
exit /b

:label
echo %1
if "%1"=="stop" goto :halt
exit /b

:halt
call :haltHelper 2> nul

:haltHelper
() 
exit /b

Using CTRL-C:

Creating an errorcode similar to the CTRL-C errorcode stops also the batch processing.
After the exit, the setlocal state is clean!
See @dbenham's answer Exit batch script from inside a function

Using advanced exception handling:

This is the most powerful solutions, as it's able to remove an arbitrary amount of stack levels, it can be used to exit only the current batch file and also to show the stack trace.
It uses the fact, that (goto), without arguments, removes one element from the stack.
See Does Windows batch support exception handling?