2

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

我尝试使用System.getenv(). 但新的价值并没有体现在程序中。场景是这样的:

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

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

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

第二次检索该值时,它应该获得修改后的值。我发现 usingSystem.getenv()只给了我旧的价值。有什么可靠的方法吗?(此要求特定于Windows,但也很想听听通用解决方案)

4

4 回答 4

2

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

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

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

尝试读取HKCU\Environment当前用户变量的密钥,以及密钥

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

有关读取注册表的有用类,请参阅有关 Windows 注册表的这个问题。

于 2012-05-03T15:09:27.113 回答
2

没有进程监视来自父进程的环境变量。甚至 C 程序也不会“监视”环境变量,因为您需要在该过程中更改它。当一个进程启动时,它会从其父进程那里获得一份环境副本。因此,如果您修改父进程中的环境变量,它不会更改子进程版本。除非您启动一个新进程,它会获得更改的副本。我认为这就是 Java 看不到这些变化的最终原因,因为它的行为就像任何正常进程一样。这种行为是有充分理由的!如果 env 变量是可修改的,那么您将遇到围绕它们的并发问题,并且您需要定义一个进程何时会“看到”来自其他进程的这些更改。这都是关于锁定、可见性、

如果你想在两个进程之间共享数据,你必须使用 IPC(进程间通信)来做到这一点。在 C 语言中,有几种方法可以做到这一点:管道、共享内存、套接字。Java 将 IPC 简化为套接字,因为它是其他两个功能的超集以及远程和本地进程之间的透明性。您可以使用管道与 Java 进程共享数据,但它会通过标准输入。

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

于 2012-05-03T15:09:28.693 回答
1

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

请看一下这篇文章,我展示了如何在没有任何外部库的情况下读取 Windows 注册表。

于 2012-05-03T15:17:08.227 回答
1

在 Win 7 上,这样的东西会得到环境变量:

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();
   . . . .

我怀疑它依赖于平台,所以你的代码的可移植性将是一个问题。

于 2012-05-03T15:20:53.603 回答