Windows为什么不能在Path中处理环境变量?


44

我和我的同事有安装Windows XP Professional x64版本的相同的Dell工作站。

我的路径环境变量开头为:

%JAVA_HOME%\bin;...

我的同事的Path变量包含使用相同环境变量指定的相同目录,但这不是他的Path中的第一项。

如果我访问系统属性->环境变量并更改JAVA_HOME变量的值,则从命令行找到的Java版本会按我的预期进行更改。这将启动一个全新的控制台窗口,以确保获取更改。

但是在我同事的机器上却没有。他继续找到他以前的Java版本,直到他调出Path变量并保存为止(即使他没有对其进行任何更改)。(同样,这是在启动全新的控制台窗口时。)

我已经在Windows上观察到大约6个月的这种不一致了,对此感到非常好奇。我们办公室中的Windows版本太多了,所以直到现在,我很少有机会在运行完全相同的OS版本的两台计算机上看到这种情况。

是什么原因造成的?为什么我的机器在我的机器上不使用新的JAVA_HOME重新评估Path?

(是因为这不是Path中的第一件事?如果是的话,那怎么可能?为什么?我会做更多的测试来检查,但是我认为他现在已经受够了并且想恢复工作)


9
对于所有投票要关闭的人(目前为3个)……如果某处有假人,请向我指出这一点肯定会很好。如果不是骗人的话,那么告诉我您对这个问题的看法是不对的。
skiphoppy

1
也许因为它比编程问题更多的是系统问题,尽管它对编程有直接影响,所以这就是为什么我不投票关闭它……:)

9
参加纳粹会议的人:我想提出一种观点,即如果在superuser.com和serverfault.com到达之前,关于Stack Overflow的问题是适当的,那么今天仍然是适当的。这是一个编程问题。
skiphoppy

您是说程序员只是Windows的用户,而他们可能会遇到此问题?闭嘴,程序员纳粹!其次,在更合适的问答站点到来之前,您没有选择在此处发布问题。SO的款待绝不能成为滥用它的理由。
2013年

我正在Windows 10中查看此问题-将变量替换为PATH 间歇性失败。转到环境变量并保存(无更改),然后打开一个新的CMD提示符即可解决此问题。
Thomas W

Answers:


37

您的路径是系统路径和用户路径的串联。此外,系统环境变量可能不包含对用户环境变量的引用,并且任何此类引用都不会扩展。为了获得所需的结果,请在用户环境变量PATH中插入对%JAVA_HOME%的引用,或者如果尚不存在则创建此类变量。

也许一个简化的例子将使这一点更加清楚。假设SYSTEM环境是

ProgramFiles = C:\Program Files
SystemRoot = C:\WINDOWS
PATH = %SystemRoot%\SYSTEM32

而用户JSmith的环境是

JAVA_HOME = %ProgramFiles%\Java\bin
USERPROFILE = C:\USERS\JSmith
PATH = %JAVA_HOME%\bin;%USERPROFILE%\bin

那么结果路径将是

C:\WINDOWS\SYSTEM32;C:\Program Files\Java\bin;C:\Users\JSmith\bin

如预期的。


3
我的系统中有一些用户环境变量与某些系统环境变量同名。回显PATH不会扩展它们-阅读此内容后,我删除了重复的用户变量,因为我想知道它们是否被优先使用(但无法扩展)。现在这对我有用-非常感谢。:)
Michael

有没有办法通过Powershell获得原始未扩展的PATH?我希望在保留未扩展的环境变量的同时追加到PATH。
CMCDragonkai

在另一个问题的帮助下解决了该问题。编写一个powershell脚本来处理此问题:gist.github.com/CMCDragonkai/a02d77c2d7c0799dd42fd2aab26a3cd5
CMCDragonkai

16

在此注册表项下签入Windows注册表:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SessionManager\Environment

如果需要扩展环境变量(此处为:%JAVA_HOME%)

那么该变量必须设置为REG_EXPAND_SZ值。

如果通过命令行使用reg.exe来添加/编辑注册表值,则默认为REG_SZ。使用该reg add /t REG_EXPAND_SZ选项指定类型REG_EXPAND_SZ 。


是的...这是我经常忘记的设置之一...讨厌的注册表;-)
Eddie B

9

当变量扩展到包含空格的路径时,在PATH变量中扩展环境变量肯定存在问题。

我们创建了自己的系统级别变量,例如“ OUR_ROOT = c:\ MyRoot”,然后在系统PATH中使用了它,例如“ PATH =;%OUR_ROOT%\ bin;”。并将其正确扩展为“ PATH =; c:\ MyRoot \ bin;”。到目前为止没有问题。

但是,在Windows 7(32位)上,我自行安装了一个产品并创建了以下系统环境变量:

STUDIO_BIN=C:\program files\Company Name\Product Name 10.4\bin

并将其添加到系统PATH变量中:

PATH=<other path elements>;%STUDIO_BIN%;<more path elements>

但是CMD中显示的PATH值包含“%STUDIO_BIN%;”。而不是扩展路径。“我的电脑”>“属性”>“高级”>“环境变量”中的值也保持不变。这意味着我无法在该目录中运行需要DLL的程序。

通过仅将STUDIO_BIN(通过“我的电脑”>“属性”>“高级...”>“环境变量”)更改为没有嵌入空格的名称:

STUDIO_BIN=C:\ProductName\bin

然后重新启动CMD窗口,PATH现在是:

PATH=<other path elements>;C:\ProductName\bin;<more path elements>

另一种解决方案是使用“我的电脑”>“属性”>“高级...”>“环境变量”对话框,充分编辑您在PATH中使用的系统变量。我尝试添加一个字符并将其删除以进行“更改”,然后确定,开始了新的CMD提示符,并且PATH未正确扩展。然后,我尝试删除部分路径,因此

STUDIO_BIN=C:\Program Files\Company Name

(省略“产品名称10.4”),瞧,下一个CMD提示显示STUDIO_BIN正确扩展的PATH!

奇怪的是,如果我返回并将“产品名称10.4”添加到STUDIO_BIN(包括我开始对其进行处理之前原来存在的所有空格),并且PATH仍正确扩展。

显然,对其内容进行了足够的更改后,PATH变量在“环境变量”对话框中进行了一些额外的处理,从而使其可以工作。当产品的安装程序添加了变量时,该处理未完成(可能只是直接在注册表中修改了PATH)。

我几乎肯定这也是XP的问题。当我组装一台新的开发机器时,它在Windows 7中重新浮出水面。显然,它尚未由Microsoft修复。

显然,即使MS定义的变量(如%ProgramFiles%)也无法在PATH中正确扩展。

如果您通过命令行或批处理文件设置PATH,则此页面可能提供答案。(将整个命令用引号引起来。)我不知道我安装的产品用来设置环境变量的安装程序是什么,但是显然需要进行任何处理才能正确扩展带有空格的路径。

所以-总而言之,您可以:

  • 将路径更改(并移动所有关联的文件)到没有空格的路径,或者

  • 在“环境变量”对话框中编辑未能扩展的变量(对其进行足够的更改以使其能够正确处理-我不确定多少已经足够)。


7

我在2009年3月的Microsoft论坛上提出了这个问题,但从未解决:

如何在Path环境变量中使用%ProgramFiles%?


我正在尝试将文件夹添加到系统的Path环境变量中。

我想添加%ProgramFiles%\ SysInternals

到现有路径变量:

C:\ PROGRA〜1 \ Borland \ Delphi5 \ Projects \ Bpl; C:\ PROGRA〜1 \ Borland \ Delphi5 \ Bin; %SystemRoot% \ system32; %SystemRoot% ;%SystemRoot%\ System32 \ Wbem; C:\ Program Files \ Microsoft SQL Server \ 80 \ Tools \ BINN; C:\ Program Files \ Microsoft SQL Server \ 80 \ Tools \ Binn \; C:\ Program Files \ Microsoft SQL Server \ 90 \ Tools \ binn \; C:\ Program Files \ Microsoft SQL Server \ 90 \ DTS \ Binn \; C:\ Program Files \ Microsoft SQL Server \ 90 \ Tools \ Binn \ VSShell \ Common7 \ IDE \; C:\ Program Files \ Microsoft Visual Studio 8 \ Common7 \ IDE \ PrivateAssemblies \;%SYSTEMROOT%\ System32 \ WindowsPowerShell \ v1.0 \

所以我去你编辑它的地方:

替代文字

我将变量添加到路径:

ProgramFiles%\ SysInternals; C:\ PROGRA〜1 \ Borland \ Delphi5 \ Projects \ Bpl; (剪断)

然后打开一个新的命令提示符窗口,环境变量不会替换为其实际值:

路径=%ProgramFiles%\ SysInternals; C:\ PROGRA〜1 \ Borland \ Delphi5 \ Projects \ Bpl(snip)>

您可以在以下屏幕截图中看到它:

替代文字


但是要回答你的问题:我不知道。似乎无法完成。


5

有两个级别的环境变量,全局变量和用户变量。如果他已将%Java_home%设置为用户环境变量,但正在更改全局变量,则不会有任何区别。


2

定义自己的用户环境变量时,请确保PATH中没有空格。例如:C:\ GNAT \ bin; C:\ GNAT \ include无法使用,因为“;”之间存在空格 和“ C:\ GNAT \ include”。


2

使用MSTSC登录到/ console会话时,添加环境变量。

重新启动计算机,您将发现环境变量将持续存在。

尝试更改环境变量时,取决于您与计算机的连接方式,操作系统中似乎有一个怪癖。


1

它可能与“延迟的环境变量扩展”功能(或缺少此功能)有关,或者您可以利用此功能始终拥有正确的解决方案。

从cmd提示符

set /? 

并阅读描述“延迟的环境变量扩展”的部分,其中包括一个要测试的小示例

set VAR=before
if "%VAR%" == "before" (
    set VAR=after
    if "%VAR%" == "after" @echo If you see this, it worked
)

如果您没有得到回声线,那可能可以解释它...

但是,如果使用/ V选项启动cmd.exe,则可以使用“!”。而不是“%”,它改变了行为

set VAR=before
if "%VAR%" == "before" (
    set VAR=after
    if "!VAR!" == "after" @echo If you see this, it worked
)

对我来说(在XP上运行),第一个脚本不起作用,但是第二个脚本却起作用(使用cmd.exe / V)


1

我遇到了同样的问题,我知道该如何解决,这很la脚。

只需再次编辑PATH,但不做任何更改,然后重新保存PATH。由于某种原因,这将导致对所有嵌套的环境变量引用进行重新评估。

如果它不起作用,请再执行几次,以某种方式使其正常工作。


1

我确实相信Windows无法扩展PATH中的变量,因为它认为尚未定义。考虑:

REM Ensure variable is undefined
SET UNDEFINED=
REM And then try to expand it
ECHO UNDEFINED=%UNDEFINED%

这个假设与我的其他观察结果相符-如果在变量更改通知时(由于加载顺序-MACHINE然后是USER)已在机器环境中定义,则%ProgramFiles%\Something用户 添加PATH将始终导致预期的扩展%ProgramFiles%。但是,当您修改计算机环境时,正确的变量扩展仅在引导时发生(现在,我不知道这种情况如何 以及为什么这种情况不会定期发生)。


1

您必须考虑登录时设置变量的顺序。如果您尝试在设置变量之前使用它,它将以空字符串形式出现。

有效的PATH是用户PATH变量后跟全局PATH变量的串联。

用户变量在全局变量之前设置,因此您不能在用户PATH变量中使用全局变量。此外,变量是按字母顺序设置的,因此您不能使用在PATH之前排序的变量。

(这至少适用于Windows7。我尚未在较新的版本上对其进行测试。)


0

也许您做错了?

我尝试使用Windows XP Pro SP3(32位)。我确实有一个路径,其中多次出现%JAVA_HOME%(和%JAVAFX_HOME%等)。我进入命令行,输入PATH,看到变量已扩展。好。

我更改的值JAVA_HOME。同样,返回相同的命令行窗口,其PATH值与预期相同(根据经验!)。

我打开一个新的命令行窗口,键入PATH,gotcha,我看到了新值。

不确定那里的确切机制是什么,但是似乎任何正在运行的程序,包括cmd.exe,都会在启动时捕获环境变量的值,并且不会回头...(尽管我相信行为良好的程序可以收听环境变化,但不太确定)。

它可能被视为功能,错误或烦恼,但这就是它的工作方式。嘿,至少与Win9X时代不同,我们不必重新启动计算机!与NT时间(IIRC)不同,您不必注销并重新登录。

为什么不一致?微软的方式是难以理解的... :-P


不是吗 更改之后,我们正在一个新的命令窗口中进行测试。我们知道以下事实:更改系统值不会更改正在运行的进程的值。
skiphoppy

好的,因此是“可能” ... :-)我的解释没有涵盖不一致之处,但可能对某些新手有用...:-PI主要是想指出变量扩展在路径中的所有地方都有效。 ..对于某些系统!(我用过的所有东西……总是32位)。

0

我已经解决了在系统>高级设置>环境变量中设置环境变量的问题

有两个面板,用户和全局变量(用户是Windows用户名)和系统变量是全局变量,因此,如果您从用户变量(例如)设置为“新建” JAVA_HOME并将其放在下面,即使全局路径也将设置变量文件夹中有程序文件。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.