环境需求
- jdk版本:
1.8
- jna依赖:
<dependency><groupId>net.java.dev.jna</groupId><artifactId>jna</artifactId><version>5.10.0</version></dependency><dependency><groupId>net.java.dev.jna</groupId><artifactId>jna-platform</artifactId><version>5.10.0</version></dependency>
获取环境变量
/*** 获取指定环境变量的内容,如果该环境变量不存在,则返回null * @param variableName 环境变量名称* @return String* @version 2.2* @author suhuamo*/public static String getEnvironmentVariables(String variableName) {// 注册表中环境变量所在位置String registryPath = "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment";try {return Advapi32Util.registryGetStringValue(WinReg.HKEY_LOCAL_MACHINE, registryPath, variableName);// 如果找不到这个环境变量,则会抛出异常} catch (Exception e) {return null;}}
重要参数介绍:
registryPath
:注册表中环境变量所在位置,即【目前打开的这个文件就是环境变量的注册表文件】WinReg.HKEY_LOCAL_MACHINE
:环境变量在注册表中的所属组,即variableName
:需要查找的环境变量的名称,即这一列的任意一个。
设置环境变量
/*** 批量写入环境变量 * @param systemEnvironmentVariables 需要写入的环境变量,<k:v> 对应 <环境变量名称:环境变量的值>* @return void* @version 2.2* @author suhuamo*/public static void setSystemEnvironmentVariables(Map<String, String> systemEnvironmentVariables){// 注册表中环境变量所在位置String registryPath = "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment";// 遍历每一组需要写入的环境变量for (Map.Entry<String, String> entry : systemEnvironmentVariables.entrySet()) {// 将该组环境变量的内容写入注册表文件中Advapi32Util.registrySetStringValue(WinReg.HKEY_LOCAL_MACHINE, registryPath, entry.getKey(), entry.getValue());}}
整合可直接使用的工具类
package org.yscz.aiks;import com.sun.jna.platform.win32.Advapi32Util;
import com.sun.jna.platform.win32.WinReg;import java.util.Map;/*** @author suhuamo* @slogan 今天的早餐是:早苗的面包、秋子的果酱和观铃的果汁~* @date 2024-01-16* @description* 操作操作系统的工具类*/
public class OSUtil {/*** 注册表中环境变量所在位置* @version 2.2* @author suhuamo* @with {@link }*/public static final String registryPath = "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment";/*** 批量写入环境变量* @param systemEnvironmentVariables 需要写入的环境变量,<k:v> 对应 <环境变量名称:环境变量的值>* @return void* @version 2.2* @author suhuamo*/public static void setSystemEnvironmentVariables(Map<String, String> systemEnvironmentVariables) {// 遍历每一组需要写入的环境变量for (Map.Entry<String, String> entry : systemEnvironmentVariables.entrySet()) {// 将该组环境变量的内容写入注册表文件中Advapi32Util.registrySetStringValue(WinReg.HKEY_LOCAL_MACHINE, registryPath, entry.getKey(), entry.getValue());}}/*** 获取指定环境变量的内容,如果该环境变量不存在,则返回null* @param variableName 环境变量名称* @return String* @version 2.2* @author suhuamo*/public static String getEnvironmentVariables(String variableName) {try {return Advapi32Util.registryGetStringValue(WinReg.HKEY_LOCAL_MACHINE, registryPath, variableName);// 如果找不到这个环境变量,则会抛出异常} catch (Exception e) {return null;}}
}
提示:
写入注册表的时候最消耗时间的是读取到注册表文件的句柄,当读取到了之后,写入注册表的耗时不到1毫秒,即如果是写入环境变量,写入1个环境变量的时间和写入100个环境变量的时间消耗时间几乎相同。
写入1个环境变量
package org.yscz.aiks;import java.util.HashMap;
import java.util.Map;/*** @author suhuamo* @slogan 巨人给你鞠躬,是为了让阳光也照射到你。* @date 2024-01-16* @description*/
public class Main {public static void main(String[] args) {long start = System.currentTimeMillis();Map<String, String> environmentVariables = new HashMap<>();environmentVariables.put("VAR1", "value1");OSUtil.setSystemEnvironmentVariables(environmentVariables);long end = System.currentTimeMillis();System.out.println("当前消耗时间:" + (end - start) + "ms");}
}
写入100个环境变量
package org.yscz.aiks;import java.util.HashMap;
import java.util.Map;/*** @author suhuamo* @slogan 巨人给你鞠躬,是为了让阳光也照射到你。* @date 2024-01-16* @description*/
public class Main {public static void main(String[] args) {long start = System.currentTimeMillis();Map<String, String> environmentVariables = new HashMap<>();for (int i = 0; i < 100; i++) {environmentVariables.put("VAR" + i, "value" + i);}OSUtil.setSystemEnvironmentVariables(environmentVariables);long end = System.currentTimeMillis();System.out.println("当前消耗时间:" + (end - start) + "ms");}
}
分析
第一个还慢一点是因为不同时间,电脑的运行内存情况不同,但可以基本上看出效率和写入环境变量的个数无关。
分析for循环中每一次写入注册表的执行速度。
/*** 批量写入环境变量* @param systemEnvironmentVariables 需要写入的环境变量,<k:v> 对应 <环境变量名称:环境变量的值>* @return void* @version 2.2* @author suhuamo*/public static void setSystemEnvironmentVariables(Map<String, String> systemEnvironmentVariables) {int idx = 0;// 遍历每一组需要写入的环境变量for (Map.Entry<String, String> entry : systemEnvironmentVariables.entrySet()) {long start = System.currentTimeMillis();// 将该组环境变量的内容写入注册表文件中Advapi32Util.registrySetStringValue(WinReg.HKEY_LOCAL_MACHINE, registryPath, entry.getKey(), entry.getValue());long end = System.currentTimeMillis();System.out.printf("第%d组环境变量写入完成,耗时%dms%n",++idx, end - start);}}
输出内容:
输出内容第1组环境变量写入完成,耗时1000ms
第2组环境变量写入完成,耗时0ms
第3组环境变量写入完成,耗时0ms
第4组环境变量写入完成,耗时1ms
第5组环境变量写入完成,耗时0ms
第6组环境变量写入完成,耗时1ms
第7组环境变量写入完成,耗时1ms
第8组环境变量写入完成,耗时1ms
第9组环境变量写入完成,耗时0ms
第10组环境变量写入完成,耗时0ms
第11组环境变量写入完成,耗时0ms
第12组环境变量写入完成,耗时0ms
第13组环境变量写入完成,耗时0ms
第14组环境变量写入完成,耗时0ms
第15组环境变量写入完成,耗时0ms
第16组环境变量写入完成,耗时0ms
第17组环境变量写入完成,耗时0ms
第18组环境变量写入完成,耗时1ms
第19组环境变量写入完成,耗时0ms
第20组环境变量写入完成,耗时0ms
第21组环境变量写入完成,耗时1ms
第22组环境变量写入完成,耗时0ms
第23组环境变量写入完成,耗时0ms
第24组环境变量写入完成,耗时0ms
第25组环境变量写入完成,耗时0ms
第26组环境变量写入完成,耗时0ms
第27组环境变量写入完成,耗时0ms
第28组环境变量写入完成,耗时0ms
第29组环境变量写入完成,耗时1ms
第30组环境变量写入完成,耗时20ms
第31组环境变量写入完成,耗时2ms
第32组环境变量写入完成,耗时1ms
第33组环境变量写入完成,耗时0ms
第34组环境变量写入完成,耗时0ms
第35组环境变量写入完成,耗时1ms
第36组环境变量写入完成,耗时0ms
第37组环境变量写入完成,耗时1ms
第38组环境变量写入完成,耗时1ms
第39组环境变量写入完成,耗时1ms
第40组环境变量写入完成,耗时0ms
第41组环境变量写入完成,耗时0ms
第42组环境变量写入完成,耗时0ms
第43组环境变量写入完成,耗时0ms
第44组环境变量写入完成,耗时1ms
第45组环境变量写入完成,耗时0ms
第46组环境变量写入完成,耗时1ms
第47组环境变量写入完成,耗时0ms
第48组环境变量写入完成,耗时0ms
第49组环境变量写入完成,耗时0ms
第50组环境变量写入完成,耗时0ms
第51组环境变量写入完成,耗时0ms
第52组环境变量写入完成,耗时0ms
第53组环境变量写入完成,耗时0ms
第54组环境变量写入完成,耗时0ms
第55组环境变量写入完成,耗时0ms
第56组环境变量写入完成,耗时0ms
第57组环境变量写入完成,耗时0ms
第58组环境变量写入完成,耗时0ms
第59组环境变量写入完成,耗时0ms
第60组环境变量写入完成,耗时0ms
第61组环境变量写入完成,耗时0ms
第62组环境变量写入完成,耗时0ms
第63组环境变量写入完成,耗时0ms
第64组环境变量写入完成,耗时6ms
第65组环境变量写入完成,耗时1ms
第66组环境变量写入完成,耗时0ms
第67组环境变量写入完成,耗时0ms
第68组环境变量写入完成,耗时0ms
第69组环境变量写入完成,耗时1ms
第70组环境变量写入完成,耗时0ms
第71组环境变量写入完成,耗时0ms
第72组环境变量写入完成,耗时0ms
第73组环境变量写入完成,耗时0ms
第74组环境变量写入完成,耗时0ms
第75组环境变量写入完成,耗时1ms
第76组环境变量写入完成,耗时0ms
第77组环境变量写入完成,耗时0ms
第78组环境变量写入完成,耗时0ms
第79组环境变量写入完成,耗时1ms
第80组环境变量写入完成,耗时0ms
第81组环境变量写入完成,耗时0ms
第82组环境变量写入完成,耗时1ms
第83组环境变量写入完成,耗时0ms
第84组环境变量写入完成,耗时0ms
第85组环境变量写入完成,耗时1ms
第86组环境变量写入完成,耗时0ms
第87组环境变量写入完成,耗时0ms
第88组环境变量写入完成,耗时1ms
第89组环境变量写入完成,耗时0ms
第90组环境变量写入完成,耗时0ms
第91组环境变量写入完成,耗时0ms
第92组环境变量写入完成,耗时1ms
第93组环境变量写入完成,耗时0ms
第94组环境变量写入完成,耗时0ms
第95组环境变量写入完成,耗时1ms
第96组环境变量写入完成,耗时0ms
第97组环境变量写入完成,耗时0ms
第98组环境变量写入完成,耗时0ms
第99组环境变量写入完成,耗时1ms
第100组环境变量写入完成,耗时0ms
当前消耗时间:1118ms
可以看到,只有第一次写入环境变量时很慢,接下来的每一次几乎都没有消耗时间:
扩展
另一种写入环境变量的方法,就是通过cmd命令setx name value /M
写入环境变量,每一次写入的时间是相同的,100ms~500ms。
/*** 设置环境变量* @param variableName* @param variableValue*/public static boolean setEnvironmentVariable(String variableName, String variableValue) {// 执行 setx 命令来设置环境变量try {String command = "setx " + variableName + " \"" + variableValue + "\" /M";Process process = Runtime.getRuntime().exec(command);// 等待命令执行完成int exitCode = process.waitFor();if (exitCode == 0) {log.info("设置:{}环境变量成功,生成内容为:{}", variableName, variableValue);} else {log.error("设置:{}环境变量失败,生成内容为:{}", variableName, variableValue);return false;}} catch (IOException | InterruptedException e) {log.error("设置环境变量时出现异常,异常原因:{}",e.getMessage());return false;}return true;}