gpt4 book ai didi

batch-file - 如何在 Windows 上仅在批处理文件中设置 PATH 环境变量一次?

转载 作者:行者123 更新时间:2023-12-04 00:55:16 25 4
gpt4 key购买 nike

我有设置用户路径并作为 Visual Studio IDE 构建步骤的一部分运行的批处理文件。

@ECHO OFF
@ECHO %PATH%
set COMSPEC = "%VCINSTALLDIR%\vcvarsall.bat" amd64
setx PATH "..\..\lib\libsndfile;..\..\lib\simulink"
@ECHO %PATH%

当我构建项目时,关闭 VS,然后重新打开它,然后重新构建,我看到附加路径作为 PATH 变量的一部分。但是,我看到在 Windows 环境变量的设置 PATH 变量是在用户环境变量下创建的

..\..\lib\libsndfile;..\..\lib\simulink

问题 1:

为什么此路径也显示为附加路径,作为系统环境变量的一部分?

在通过 Visual Studio 控制台执行 echo %PATH% 时(当我第二次运行项目时)打印系统变量路径和我创建的新路径附加到它。

问题 2:

我想修改我的批处理文件,使其在 Visual Studio 构建的首次运行期间仅在用户设置中设置一次 PATH 环境变量。如果用户变量PATH在后续运行中已经存在,则不应再次执行set命令,以免在系统变量中反复追加新路径。

任何想法如何实现这一目标?

最佳答案

编辑:经过一些测试,看来我的原始答案并不完全适用于 OP 的问题。更直接地回答OP:

  1. %PATH%HKLM\System\CurrentControlSet\Control\Session Manager\Environment\Path 中的值与 HKCU\Environment\Path 结合起来。当您 setx "dir;dir" 时,您设置的是 HKEY_CURRENT_USER Path 值。机器范围的 HKEY_LOCAL_MACHINE Path 值保持不变。这就是为什么您将您的值视为附加而不是替换的原因。您必须使用 setx/m 替换 HKLM Path 值。 但请不要这样做,除非您想对操作系统安装造成严重问题。

  2. 如果要测试%PATH%中是否存在目录,可以cdpushd都到目录您要检查 %PATH% 中的每个目录以统一每个目录,确保所有相对路径、环境变量等都被展平。 为每个设置“var=%CD%”。然后 if/I "!dir1!"=="!dir2!" 目录已经存在于 %PATH% 的某个地方。我在下面的原始答案中有一个例子。

我最初的答案并不完全适用的原因是 setx 本身并不像我曾经想象的那样具有破坏性。危险在于,通常当用户想要将目录附加到他们的路径时,他们会 setx/m PATH "%PATH%;new dir";这破坏性的。由于 %PATH%setx 写入值之前展开,因此 PATH 中的所有目录都过早展开。

以下方法会更安全:

set "env=HKLM\System\CurrentControlSet\Control\Session Manager\Environment"

for /f "tokens=2*" %%I in (
'reg query "%env%" /v Path ^| findstr /i "\<Path\>"'
) do setx /m PATH "%%J;new directory"

但这并不是 OP 真正要求的,我为下意识的回答道歉。


原始答案: setx 具有破坏性,不应以这种方式使用。当您 setx PATH 时,您将注册表值数据类型从 REG_EXPAND_SZ 转换为 REG_SZ。执行此操作后,存储在 %PATH% 中的所有动态环境变量都会转换为平坦的绝对路径。使用 path 命令将目录临时附加到您的 %PATH%,并使用 reg add 永久附加目录。 (附带说明一下,还有 dpath,它会临时将目录添加到您的路径中,但只能由 type 命令使用。向下滚动 2/3 this page 了解更多关于 dpath 的信息。)

这是我编写的实用程序脚本,用于以破坏性较小的方式将目录添加到我的 %PATH% 中。它还将避免多次将同一目录添加到 %PATH%,无论其格式如何(例如尾随反斜杠、相对路径、环境变量或任何其他排列)。

@echo off
setlocal enabledelayedexpansion

if not exist "%~1" goto usage

for %%I in ("%~1") do pushd "%%~I" 2>NUL && (set "new=!CD!" && popd) || goto usage
for %%I in ("%PATH:;=";"%") do pushd "%%~I" 2>NUL && (
rem // delaying expansion of !new! prevents parentheses from breaking things
if /i "!new!"=="!CD!" (
echo !new! already exists in %%PATH%%
goto :EOF
)
popd
)

call :append_path "%new%"

goto :EOF

:usage
echo Usage: %~nx0 "dir"
goto :EOF

:append_path <val>
set "env=HKLM\System\CurrentControlSet\Control\Session Manager\Environment"
for /f "tokens=2*" %%I in ('reg query "%env%" /v Path ^| findstr /i "\<Path\>"') do (

rem // make addition persistent through reboots
reg add "%env%" /f /v Path /t REG_EXPAND_SZ /d "%%J;%~1"

rem // apply change to the current process
for %%a in ("%%J;%~1") do path %%~a
)

rem // use setx to set a temporary throwaway value to trigger a WM_SETTINGCHANGE
rem // applies change to new console windows without requiring a reboot
(setx /m foo bar & reg delete "%env%" /f /v foo) >NUL 2>NUL

color 4E
echo Warning: %%PATH%% has changed. Reopen the console to inherit the changes.

goto :EOF

关于batch-file - 如何在 Windows 上仅在批处理文件中设置 PATH 环境变量一次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31885906/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com