获取 Windows 中定义的环境变量(不是特定于进程的)

Get environment variables as defined in Windows (not process specific)

我正在尝试构建一个 Java 可以编辑环境变量的应用程序(如果可能甚至区分系统变量和用户变量),基本上与 [=35] 中的环境变量编辑器完全相同=] 7,只是有一个更容易使用的界面:
是的,我知道有些应用程序正是这样做的,但我想自己编写代码(作为练习和娱乐)。

但是我的问题是,当获取这些变量时,它总是returns当前在此过程中设置的变量(参见示例)。
有没有办法获取 Windows 中设置的变量?
我尝试从 java 启动一个 cmd.exe 新进程并执行 SET,但新进程继承了变量。
为了持久化它们,我想我会使用 SETX 命令,但我还没有测试它。

我只需要 Windows 7 的解决方案,不需要它与任何其他 OS.

一起使用

示例:
路径是:'c:\apps\oracle\clients{...}\Microsoft SQL Server0\DTS\Binn\'
但是在我的 Java 应用程序中它以 'java\jdk1.8.0_181\jre\bin' 结尾。
JDK 1.8 不在我的全局路径变量中,只存在于当前进程中。

我使用了 Windows 注册表,正如 DodgyCodeException 所建议的那样。 为了访问它,我使用了 JNA

示例代码(使用系统变量,为参数 'user' 传递 true 以使用用户变量):

public static final String USER_VAR_PATH = "Environment";
public static final String SYSTEM_VAR_PATH = "SYSTEM\CurrentControlSet\Control\Session Manager\Environment";

public static void main(String[] args) {
    //Get all system environment variables
    for(String systemVariableName : getAllEnvironmetVariables(false).keySet()){
        System.out.println(systemVariableName);
    }

    //print system environment variable 'OS'
    System.out.println(getEnvironmetVariable("OS", false));

    //write to the path variable (append a string)
    String addToPath = "";
    setEnvironmetVariable("Path", getEnvironmetVariable("Path", false) + addToPath, false);
}

public static TreeMap<String, Object> getAllEnvironmetVariables(boolean user){
    HKEY root = user ? WinReg.HKEY_CURRENT_USER : WinReg.HKEY_LOCAL_MACHINE;
    String path = user ? USER_VAR_PATH : SYSTEM_VAR_PATH;
    return Advapi32Util.registryGetValues(root, path);
}

public static String getEnvironmetVariable(String key, boolean user){
    HKEY root = user ? WinReg.HKEY_CURRENT_USER : WinReg.HKEY_LOCAL_MACHINE;
    String path = user ? USER_VAR_PATH : SYSTEM_VAR_PATH;
    try{
        return Advapi32Util.registryGetExpandableStringValue(root, path, key);
    }catch(Exception e){
        return Advapi32Util.registryGetStringValue(root, path, key);
    }
}

public static void setEnvironmetVariable(String key, String value, boolean user){
    HKEY root = user ? WinReg.HKEY_CURRENT_USER : WinReg.HKEY_LOCAL_MACHINE;
    String path = user ? USER_VAR_PATH : SYSTEM_VAR_PATH;
    if(value.contains("%")){
        Advapi32Util.registrySetExpandableStringValue(root, path, key, value);
    }else{
        Advapi32Util.registrySetStringValue(root, path, key, value);
    }
}

变量使用两种类型的值:REG_SZREG_EXPAND_SZ
都是字符串,但第二个表示包含其他变量(如%SystemRoot%\...
我对这两种类型的处理应该有效,但绝对不干净。如果有更好的方法请告诉我

编辑:您需要 JNA and JNA Platform 才能正常工作。 进口是:

import com.sun.jna.platform.win32.Advapi32Util;
import com.sun.jna.platform.win32.WinReg;
import com.sun.jna.platform.win32.WinReg.HKEY;