我已成功使用CALL机制允许一个批处理文件调用另一个批处理文件来设置环境变量。这段代码在Windows XP上运行了一年多。
但是,它似乎在Windows 7上的工作方式不同。变量存在于EXIT / B语句之前的第二个批处理文件中。但是,在返回第一批文件时它们不存在。
一些琐碎的例子似乎按预期工作,但大批量脚本没有。
有没有人遇到过这方面的困难或知道任何变通办法?
答案 0 :(得分:6)
在多年的高级批处理脚本中,我从未见过CALL无法保留环境变量,除非被调用的脚本(或标签)在SETLOCAL仍处于活动状态时设置变量。在CALL终止时,CALL内的每个活动SETLOCAL都有一个隐含的ENDLOCAL。
听起来您在EXIT / B之前输入了诊断消息,以确认您的变量已定义。我会更进一步,在诊断消息之前添加多个ENDLOCAL语句。我怀疑你会在EXIT / B之前看到你的值消失。您可以根据需要添加任意数量的ENDLOCAL。 ENDLOCAL永远不会影响在CALL之前发生的SETLOCAL。
最可能的解释是,您的脚本在某种程度上已经从XP更改为Win 7,或者您的Win 7环境中存在一些上下文更改,这些环境正在执行之前未公开的代码的某些方面。 / p>
答案 1 :(得分:0)
试试这个:
(
ENDLOCAL
SET "_Var1=Some Variable You want to exist"
SET "_Var2=Some Other Variable You want to exist"
EXIT /b 0
)
还要确保从批处理1调用批处理2,如下所示:
CALL "\\PathToBatch2\Batch2.cmd"
ALTERNATELY你可以这样做:
CMD One:
REM Script: Batch1
@(
SETLOCAL
ECHO OFF
SET "_CallBatch2=C:\PathToBatch2\Batch2.cmd"
SET "_SetCmd=CALL :SetCMD "
SET "_RecievedVarList="
SET "_RecievedVar1=" & REM -- Note only done to show this is being created, normally you won't know or care what variables are being returned.
SET "_eLvL=0"
)
CALL :Main
(
ENDLOCAL
EXIT /b %_eLvl%
)
:Main
FOR %%A IN (CALL "%_CallBatch2%") DO (
IF /I "%%~A" EQU "SET" (
REM CALL %%A "%%~B" would work too
%_SetCmd% %%~B
) ELSE (
REM Looks like this was intended to be some output, show it.
ECHO.%%A %%B
)
)
FOR /F "Tokens=1*" %%A IN (%_RecievedVarList%) DO (
REM ECHO the Variable's name and it's contents:
CALL ECHO."%%~A" = "%%%%~A%%"
)
GOTO :EOF
:SetCMD
SET "%*"
FOR /F "Tokens=1 Delims==" %A IN ("%*") DO (
REM Store vars to output later to check their values.
SET "_RecievedVarList=%_RecievedVarList% "%A""
)
GOTO :EOF
CMD二:
REM Script: Batch2
@(
SETLOCAL
ECHO OFF
)
CALL :Main
(
ENDLOCAL
EXIT /b %_eLvl%
)
:Main
ECHO.SET "_RecievedVar1=This is Recieved Var 1"
ECHO.SET "_RecievedVar2=This is Recieved Var 2"
GOTO :EOF