Reputation: 41
I have a subroutines which is called to check ERRORLEVEL
.
The subroutine calls other subroutines to log msgs, send email, then Exit out of the script. It goes to :END
, then returns to the stmt after the call
@echo off
echo starting...
call:checkTime
echo +++ after CT
GOTO:END
:checkTime
echo the time is %TIME%
goto:END
goto:EOF
:END
Upvotes: 4
Views: 6281
Reputation: 130839
The question is poorly worded, but I think I understand (especially if I concentrate on the title)
My interpretation of your problem:
At various points in your batch file, you check the ERRORLEVEL. Whenever you detect an error, you want to perform some standard error processing, and then exit the batch script. You attempted to create a subroutine to do the standard processing, but the subroutine returns to the caller instead of exiting the script. Your question is, how do you force your error processing routine to exit instead of returning to caller?
Answer:
If none of your error detection occurs within a called subroutine, then you can simply GOTO your error processor instead of CALLing it.
If you want to be able to call the routine and exit from within another called routine, then you can continue to use the CALL
statement, but terminate your error routine with EXIT
instead of GOTO :EOF
or GOTO :END
.
Addendum in response to comment
Yes, GOTO cannot pass parameters, and a CALLed routine will always return to the caller (unless the routine ends with EXIT)
And yes, EXIT will close the current CMD shell, which will usually close the console window.
BUT... you can have the batch file execute itself through another CMD shell, so that EXIT does not close the window!
The only potential drawback to this that I see is changes to the environment will be lost once the batch file (and the CMD shell that is running it) terminates. That may or may not be a problem for you.
@echo off
if "%~1" equ "_GO_" goto :main
cmd /c ^""%~f0" _GO_ %*^"
exit /b
:main
shift /1
echo %%1=%1 %%2=%2
echo before call
call :exitRoutine
:: should not get here
echo after call
exit /b
:exitRoutine
echo exiting batch file witin exitRoutine
exit
Upvotes: 5
Reputation: 67216
Yes, this is the expected behavior: a subroutine called via CALL
command may end in three different ways: executing EXIT [/B]
, executing GOTO :EOF
or just reaching the end of the file. All three ways cause to return to the calling program. By the while, "GOTO command now accepts a target label of :EOF which transfers control to the end of the current batch script file. This is an easy way to exit a batch script file without defining a label." (from GOTO /?
), so really the second and third methods are the same.
If you want to sometimes return from the subroutine, but other times to terminate the calling program, then your subprogram can NOT be executed via CALL
, but in other different way. If you want to pass parameters to the subprogram, then it must be a separate .BAT file that will be executed via its name with parameters and NO call, for example:
subprogram param1 param2 ...
This way, in order for this subprogram to "return" to the calling program, it must know to wich Batch file and in what line it must return. This information may be set by the calling program via variables; the calling program must also determine if it is running in normal way or because the return of the false subroutine. You may do that this way:
main.bat:
@echo off
rem If this is a false subroutine return: complete it
if "%1" == "return" goto %2
rem Do my usual business
rem . . .
rem Execute the subprogram as subroutine
set caller=main
set returnPoint=label23
subprogram param1 param2
:label23
rem Continue after subprogram return...
subprogram.bat:
rem Do my business
rem . . .
rem To return to the caller:
%caller% return %returnPoint%
rem . . .
rem To terminate here, execute EXIT /B, GOTO :EOF, or just reach the end
Sorry, there is no easy way to do this...
Upvotes: 3