如何在Java程序中检索环境变量(在外部修改)的修改值?

时间:2012-05-03 15:01:28

标签: java runtime environment-variables

是否可以在Java程序中检索环境变量的修改值?

我尝试使用System.getenv()。但新的价值并未反映在该计划中。场景是这样的:

  1. 程序检索环境变量的值。

  2. 此变量的值在外部更改,而程序仍在运行。 (它甚至可以是手动过程,例如,在Windows中,用户更改“我的电脑”中的“高级”选项卡中的值 - >属性)

  3. 程序再次检索环境变量的值。

  4. 第二次检索值时,它应该获得修改后的值。我发现使用System.getenv()只给了我旧的价值。有没有可靠的方法呢? (此要求特定于 Windows ,但也希望听到一般解决方案)

4 个答案:

答案 0 :(得分:2)

Afaik,流程可见的环境变量在流程创建时设置。

对OS变量的后续修改对于除了更改它们之外的进程不可见。

但是,根据操作系统,可能有某种方法可以检索它们。例如。在Windows Os上,它们保存在注册表中,因此您可以从中读取它们。

尝试在HKCU\Environment处读取当前用户变量的密钥和密钥

HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment for system variables.

有关阅读注册表的有用类,请参阅this question about Windows registry

答案 1 :(得分:2)

没有进程从父级监视环境变量。甚至C程序也不会“监视”环境变量,因为您需要在该过程中更改它。当进程启动时,它会从其父进程获取环境的副本。因此,如果您修改父级中的环境变量,则它不会更改子进程版本。除非您启动一个新流程,否则它会获得更改的副本。而且我认为这最终是Java没有看到变化的原因,因为它的行为就像任何正常流程一样。这种行为有充分的理由!如果env变量是可修改的,那么你将遇到围绕它们的并发问题,并且你需要定义一个进程何时“看到”来自其他进程的那些变化。这就是大多数操作系统在早期都不想解决的锁定,可见性和令人讨厌的并发问题。

如果要在两个进程之间共享数据,则必须使用IPC(进程间通信)来执行此操作。在C land中有几种方法可以做这个管道,共享内存,套接字。 Java将IPC简化为套接字,因为它是其他两个版本的能力的超集以及远程和本地进程之间的透明度。您可以使用管道与Java进程共享数据,但它可以通过stdin。

Java中的底线启动套接字,并从另一个进程发送数据。

答案 2 :(得分:1)

除了@Andrea Parodi(+1)的答案之外,我真的可以建议您通过运行外部命令行echo %MYENV_VAR%来读取环境并读取输出或读取注册表。

请查看this article,了解如何在没有任何外部库的情况下阅读Windows注册表。

答案 3 :(得分:1)

在Win 7上,类似这样的内容将获得env vars:

Process p = Runtime.getRuntime().exec("cmd.exe /c set");
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
while( (line = br.readLine()) != null ) {
   String var = br.readLine();
   . . . .

我怀疑它的平台依赖,因此代码的可移植性将成为一个问题。