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

时间:2018-12-19 14:03:44

标签: java cmd windows-7 environment-variables

我正在尝试构建一个Java应用程序,该应用程序可以编辑环境变量(如果可能,甚至可以区分系统变量和用户变量),基本上与Windows 7中的“环境变量编辑器”做完全相同的事情,并且使用起来更简单接口: Windows 7 Environment Variable Editor
是的,我知道有很多应用程序可以做到这一点,但是我想自己编写代码(作为练习,很有趣)。

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

我只需要Windows 7的解决方案,而无需与其他任何操作系统一起使用。

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

1 个答案:

答案 0 :(得分:0)

我使用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%\...
我对这两种类型的处理应该可以,但绝对不干净。如果有更好的方法,请告诉我。

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

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