There are two (2) Windows batch scripts. The first one will CALL the second one. However, SETLOCAL must be used around the call to the second batch script because ENABLEDELAYEDEXPANSION is needed in a FOR loop.
=== batch1.bat
@echo off
echo in %0
set BAT1_VAR=5
SETLOCAL
call batch2.bat
set|find "BAT"
echo === before endlocal
ENDLOCAL
set|find "BAT"
echo === after endlocal
echo === begin exiting %0
set|find "BAT"
echo === end exiting %0
exit /B 0
=== batch2.bat
@echo off
echo in %0
SET BAT2_VAR=7
echo === begin exiting %0
SET|FIND "BAT"
echo === end exiting %0
EXIT /B 0
===
The problem is that the variable set by batch2.bat needs to still exist after the return to batch1.bat. This can be resolved by using:
ENDLOCAL & set BAT2_VAR=%BAT2_VAR%
HOWEVER, I do not want batch1.bat to need to know the names of variables created by batch2.bat. There might be many and the list may change.
Any ideas to overcome this problem? Thanks.
If you are in a loop, or any parenthesized block of code, then you cannot use the
ENDLOCAL & set BAT2_VAR=%BAT2_VAR%method.Something like this would fail
A simple fix is to transfer the value via a FOR variable
You say your batch might set many values you need to preserve. Normally you pass the names of the return variables into your CALLed routine, and then your routine could do something like:
You would know the names of all the variables, but that might require a lot of code to transport all values accross the endlocal barrier.
You could prefix all the variables with a common prefix, and then use a FOR /F loop to preserve the values. The entire result set of a FOR /F (‘command’) is cached before any of the iterations begin.
Your CALLed batch could set variables
prefix.var1,prefix.var2, …prefix.varN, and the following code would workThe
if "!"=="" endlocalline is a nifty trick to only endlocal on the 1st inner loop iteration. It relies on the fact that delayed expansion was disabled before the outer loop, and enabled near the top of each outer loop iteration.