如何在Windows 7中从批处理文件中持续设置变量?

47

我正在尝试使用批处理文件在Windows 7中设置PATH环境变量,但似乎没有生效。

我正在使用以下Windows命令:

set PATH=%cd%;%path%
pause

不过,这种方法似乎只在当前的cmd实例中才有效。我想要让它变成永久的,因为我首先设置了PATH,然后运行一个需要在该文件夹中定位库的程序。


如果你切换到那个目录,你的程序不就会捕捉到它们吗?也许你可以通过绕过这个问题来解决它? - Jon
@Jon,依赖于工作目录进行DLL搜索是不是很危险?最好的方法是将DLL放在与.exe相同的目录中,这样就没有错误的余地了。 - David Heffernan
@DavidHeffernan:我不会说这是“危险的”。无论如何,这个决定已经由Microsoft和/或程序的作者做出,所以不能改变。你的答案很好(事实上我是你的+1),但也许这可以在30秒内解决? - Jon
7个回答

66

使用 setx.exe 代替 set。

setx PATH "%cd%;%path%;"
pause
注意,这将为所有未来的 cmd 实例设置路径,但不包括当前实例。如果需要这样做,请运行原始的 set 命令。
更新:如果第二个参数包含空格(%path% 中总是有空格),则需要用引号引起来。请注意,如果 %path% 的最后一个字符是反斜杠,则会转义末尾的引号,并且最后一个路径条目将停止工作。 通过在闭引号之前附加分号来避免这个问题。
如果您不想冒险在重复运行后在路径末尾获得“;;;;;;”,那么可以在设置之前从 %path% 变量中删除任何尾随的反斜杠,然后它将正常工作。

12
请注意,这两个命令的区别在于缺少等号符号,并且它们的语法非常相似,容易混淆。 - Andriy M
好的,无法链接到带有尾随反斜杠讨论的线程(为什么帖子不能包含那个内容,你这个愚蠢的网站?!)。搜索“setx path spaces”以找到我所说的线程。 - Ryan Bemrose
23
如果你执行 SETX PATH "%PATH%;C:\My\App" /M 命令时,请小心,因为 %PATH% 变量会扩展为用户路径和系统路径,这可能会使整个 %PATH% 超过1024个字符的限制,导致重复出现某些条目。更好的方法是从 PATH 命令获取字面值,然后使用 SETX 设置一个字面值。 - Wayne Bloss
Wizlb,这是一个很好的观点,但当我设置%PATH%或回显%PATH%时,我只能看到我的笔记本电脑上的系统变量。你确定吗? - Millemila
3
@wizlb好的警告,它读取警告:保存的数据被截断为1024个字符。它把它搞砸了。 - n611x007
显示剩余2条评论

22
如果你想在批处理文件中执行此操作,请使用 reg 命令更改注册表中 HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment 键处的路径值。示例如下:
reg add "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v Path /t REG_SZ /d "%path%;c:\newpath"

检查%path%变量中的路径是否与系统路径相匹配。


7
当你的路径长度超过1024个字符时,这是一个更好的主意。 - Dhawalk
1
我不得不重新启动计算机以应用更改。 - Genhis
1
请注意,当您使用 %path% 时,它将展开任何在 %path% 中的变量。我认为您可以使用 setlocal EnableDelayedExpansion 来防止这种情况发生。 - Reed Hedges

18

正如wizlb所指出的那样,做

setx PATH "%cd%;%path%;" -m

将本地环境变量复制到系统环境变量中,没有-m参数将会把系统环境变量复制到用户环境变量中,这两种情况都不理想。为了准确地编辑注册表的某一部分(系统或用户,在下面的示例中是系统),您需要执行以下操作:

for /F "tokens=2* delims= " %%f IN ('reg query "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v Path ^| findstr /i path') do set OLD_SYSTEM_PATH=%%g
setx.exe PATH "%OLD_SYSTEM_PATH%;%OTHER_STUFF%;" -m

解决方案的功劳归功于http://www.robvanderwoude.com/ntregistry.php


3
好的回答!其他解决方案将把变量扩展为常量(如SystemRoot、JAVA_HOME等),而您的解决方案将保留它们。 - Jako
一个需要注意的地方是,在更改生效之前,您可能需要重新启动Windows。我忘记了具体是哪里有问题,所以如果您看到任何奇怪的东西,请重新启动并重试。 - DenNukem
请删除您代码中的 delims=。在我(已退役)的WinXP上,reg query 使用 TAB 而不是空格来分隔项目!在典型的输出行中,我们可以在四个前导空格之后识别:值名称 TAB 值类型 TAB _值_。 - JosefZ
+1 表示 -m。我的一个应用程序(将应用程序作为服务运行)要求我设置系统变量(而不是用户变量)。结果发现,我漏掉了 -m 开关。 - Tyagi Akhilesh

12
为了正确地完成这项任务,我认为你需要超越简单的批处理文件。根据MSDN文档的说明:
要以程序方式添加或修改系统环境变量,将它们添加到注册表键HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment中,然后广播带有lParam设置为字符串“Environment”的WM_SETTINGCHANGE消息。这允许应用程序(例如shell)获取您的更新。
首先,您将无法在没有用户帐户控制提示的情况下写入该键。最好通过向可执行文件添加适当的清单来安排。其次,从批处理文件广播WM_SETTINGCHANGE并不简单。
在您的位置上,我会编写一个简短而简单的控制台应用程序来完成此任务。

1
你可能会对名为SendMessage的实用工具感兴趣,该工具可以从stefanstools sf net广播你的WM_SETTINGCHANGE源讨论质疑是否有原生vbscript可用于此目的的API包装程序潜伏在某处。 - n611x007

4

一个简单(可能更好)的解决方案是使用PathMgr.cmd

https://gallery.technet.microsoft.com/Batch-Script-To-Manage-7d0ef21e中下载pathmgr_1.0.2.zip

解压并将pathmgr.cmd放置在与批处理文件相同的文件夹中,然后在批处理文件中编写以下两行:

call pathmgr.cmd /del %cd% /y
call pathmgr.cmd /add %cd% /y

这将会:
1)仅更新用户变量 PATH, 2)不会多次包含系统 PATH。
您也可以多次运行批处理文件,它只会在 PATH 中包含当前路径一次。

0

假设我想创建一个名为"ZIP_PROGRAM"的系统环境变量,并将其指向路径为"C:\Program Files\7-Zip\7z.exe"的可执行文件。

我将在DOS提示符下执行以下操作:

步骤1:执行以下代码: reg add "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v ZIP_PROGRAM /t REG_SZ /d "C:\Program Files\7-Zip\7z.exe" /f

步骤2:注销,然后登录

步骤3:打开DOS提示符并执行:"set z",您应该能够看到系统环境变量已更新


0

使用以下命令

setx PATH "%PATH%;%MVN_HOME%\bin\"

无论如何,它不会在当前会话中设置,您需要使用

set PATH="%PATH%;%MVN_HOME%\bin\"


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接