Windows batch file - return values to caller

How to use setlocal inside your batch file but still set an environment variable in the caller (a bit like a return value).

It is good practice for batch files to include setlocal to limit environment changes to within the scope of that batch file and not impact the callers environment. This gives you free reign to use whatever variables or path changes you like without fear of impacting the caller -- a much cleaner way to develop usable and reusable scripts.

I will routinely always include this at the top of every BAT file...

@echo off
setlocal ENABLEDELAYEDEXPANSION

(note that delayed variable expansion is another topic altogether but I like it and usually enable it by default)

But how do you use setlocal AND then return something to the caller?

One possibility is the ERRORLEVEL functionality, effectively a return code. Your batch file can use a construct such as...

EXIT /B 2

...to exit this script and set the error level to 2. The caller can then check that return code with...

IF ERRORLEVEL 2 echo Returned errorlevel was 2

Note that IF ERRORLEVEL actually checks if the error level is 2 or greater so be careful. You could use %ERRORLEVEL% instead to check exact match.

Either way, not very flexible and constrained to the particular use case of "return codes", which overlaps with executable exit code functionality, so it's fine if that's what you want to do.

An alternative is to use ENDLOCAL and set your return value (or values) on the same line - this lets you get variable substitution from your environment AND set a variable in the callers environment.

(obviously at that point you are changing the value in the callers environment so you need to have agreed which variable(s) is being used to pass information around)

Some code like this:

SET v=some_status_to_return
ENDLOCAL & SET retv=%v%
goto :eof

Takes your local value of v and writes it to callers environment variable retv.

It works because the text substitution (for %v% in above example) happens on the whole line before any parsing or execution of the line -- as soon as ENDLOCAL is executed then all your variables get lost and the environment returned to the callers. BUT the text of the line being executed gets to hold the value you want returned and executed in the SET, in the second half of the statement following the '&' separator.