我正在尝试构建一个Java应用程序,该应用程序可以编辑环境变量(如果可能,甚至可以区分系统变量和用户变量),基本上与Windows 7中的“环境变量编辑器”做完全相同的事情,并且使用起来更简单接口:
是的,我知道有很多应用程序可以做到这一点,但是我想自己编写代码(作为练习,很有趣)。
但是我的问题是,在获取这些变量时,它总是返回当前在此过程中设置的变量(请参见示例)。
有没有办法获取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不在我的全局路径变量中,仅在当前进程中存在。
答案 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_SZ
和REG_EXPAND_SZ
。
都是字符串,但是第二个字符串表示它包含其他变量(例如%SystemRoot%\...
)
我对这两种类型的处理应该可以,但绝对不干净。如果有更好的方法,请告诉我。
编辑:您需要JNA和JNA Platform才能正常工作。 进口是:
import com.sun.jna.platform.win32.Advapi32Util;
import com.sun.jna.platform.win32.WinReg;
import com.sun.jna.platform.win32.WinReg.HKEY;