如何将变量的值保留在使用"延迟扩展本地"模式的Windows批处理脚本之外?

Von*_*onC 8 windows path batch-file environment-variables

上下文:我需要调用一个Windows批处理脚本,PATH通过xxx在其末尾添加另一条路径来更新我,但是:

  • 没有任何重复
    (如果我添加' xxx'到PATH' aaa;xxx;bbb'',我需要更新PATH像' aaa;bbb;xxx')
  • 没有任何聚合
    (我可以反复调用脚本而不用' aaa;bbb;xxx;xxx;xxx;...' 结束)

我尝试过的:

以下功能负责处理任何重复并完成工作

:cleanAddPath -- remove %~1 from PATH, add it at the end of PATH
SETLOCAL ENABLEDELAYEDEXPANSION
set PATH=!PATH:%~2=!
set PATH=!PATH:;;=;!
set PATH=%PATH%;%~2
set P=!P:;;=;!
echo %PATH%
echo -------------
ENDLOCAL  
exit /b
Run Code Online (Sandbox Code Playgroud)

但是,它需要延迟扩展本地模式,这意味着:在脚本结束时(或者在这里,在函数结束时cleanAddPath),已经设置的任何内容都被%PATH%丢弃.

我可以要求用户(我为其编写脚本)启动他们cmdcmd /V:ON选项(激活延迟扩展,否则默认关闭),但这是不切实际的.

如何按PATH上述方式修改变量,并调用所述脚本仍在当前的DOS会话中更新?

Von*_*onC 6

页面" DOS - 函数集合 "提供了一个很好的例子,说明函数如何在DOS中返回一个值,即使使用延迟扩展模式:

以下函数将通过添加更新所需的任何变量PATH:

:cleanAddPath -- remove %~2 from %~1, add it at the end of %~1
SETLOCAL ENABLEDELAYEDEXPANSION
set P=!%~1!
set P=!P:%~2=!
set P=!P:;;=;!
set P=!P!;%~2
set P=!P:;;=;!
(ENDLOCAL & REM.-- RETURN VALUES
  SET "%~1=%P%"
)
exit /b
Run Code Online (Sandbox Code Playgroud)

请注意使用的路径串联.正如杰布 评论:

set P=%P%;%~2如果您的路径包含类似于的&符号,则该行至关重要C:\Documents&Settings.
更好地改变设置" P=!P!;%~2".

SET "%~1=%P%"是,其允许记忆(在由表示的可变部分%~1)您已使用延迟扩展等功能设置的值.
我最初使用过 SET "%~1=%P%" !,但是jeb 评论:

该命令SET "%~1=%P%" !可以简化SET "%~1=%P%"为尾随感叹号在延迟扩展模式中只有(良好)效果,如果您%P%之前准备好了.

要更新PATH变量,您可以使用以下命令调用函数:

call :cleanAddPath PATH "C:\my\path\to\add"
Run Code Online (Sandbox Code Playgroud)

对于当前的DOS会话,它将在离开该脚本后继续存在.

dbenham答案指向一个更强大的答案(upvoted),但在我的情况下,这个脚本就足够了.