使用java批量写入环境变量的实现

 更新时间:2024年03月08日 08:31:25   作者:人间花木  
本文主要介绍了使用java批量写入环境变量,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

环境需求

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:注册表中环境变量所在位置,即【目前打开的这个文件就是环境变量的注册表文件】

image.png

WinReg.HKEY_LOCAL_MACHINE:环境变量在注册表中的所属组,即

image.png

variableName:需要查找的环境变量的名称,即

image.png

这一列的任意一个。

设置环境变量

    /**
     * 批量写入环境变量 
     * @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");
    }
}

image.png

写入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");
    }
}

image.png

分析

第一个还慢一点是因为不同时间,电脑的运行内存情况不同,但可以基本上看出效率和写入环境变量的个数无关。

分析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

可以看到,只有第一次写入环境变量时很慢,接下来的每一次几乎都没有消耗时间:

image.png

image.png

扩展

另一种写入环境变量的方法,就是通过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;
    }

到此这篇关于使用java批量写入环境变量的实现的文章就介绍到这了,更多相关java批量写入环境变量内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家! 

相关文章

  • Java中常见字符串拼接九种方式详细例子

    Java中常见字符串拼接九种方式详细例子

    这篇文章主要给大家介绍了关于Java中常见字符串拼接的九种方式,字符串拼接是我们在Java代码中比较经常要做的事情,就是把多个字符串拼接到一起,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2023-07-07
  • Java 操作Properties配置文件详解

    Java 操作Properties配置文件详解

    这篇文章主要介绍了Java 操作Properties配置文件详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07
  • Java Web项目中实现文件下载功能的实例教程

    Java Web项目中实现文件下载功能的实例教程

    这篇文章主要介绍了Java Web项目中实现文件下载功能的实例教程,分别讲解了通过超链接实现下载以及通过Servlet程序实现下载的方式,需要的朋友可以参考下
    2016-05-05
  • springboot 使用上下文获取bean

    springboot 使用上下文获取bean

    这篇文章主要介绍了springboot 使用上下文获取bean,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-07-07
  • SpringBoot整合ZXing实现二维码和条形码的创建

    SpringBoot整合ZXing实现二维码和条形码的创建

    如今我们越来越多的东西需要用到二维码或者条形码,商品的条形码,付款的二维码等等,所以本文小编给大家介绍了SpringBoot整合ZXing实现二维码和条形码的创建,文章通过代码示例给大家介绍的非常详细,需要的朋友可以参考下
    2023-12-12
  • java单例五种实现模式解析

    java单例五种实现模式解析

    这篇文章主要介绍了java单例五种实现模式解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-09-09
  • Java并发系列之AbstractQueuedSynchronizer源码分析(概要分析)

    Java并发系列之AbstractQueuedSynchronizer源码分析(概要分析)

    这篇文章主要为大家详细介绍了Java并发系列之AbstractQueuedSynchronizer源码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-02-02
  • DUCC配置平台实现一个动态化线程池示例代码

    DUCC配置平台实现一个动态化线程池示例代码

    这篇文章主要为大家介绍了DUCC配置平台实现一个动态化线程池示例代码,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-02-02
  • 详解Java中如何定义和访问静态字段和方法

    详解Java中如何定义和访问静态字段和方法

    在面向对象的程序设计中,我们通常使用类来创建对象,类中有许多成员变量和方法,它们是直接属于对象实例的,与之对应的还有一类成员,那就是静态成员,本文就来和大家聊聊Java是如何定义访问静态成员的吧
    2023-05-05
  • Spring Bean作用域与生命周期深入讲解

    Spring Bean作用域与生命周期深入讲解

    这篇文章主要介绍了浅谈Spring中Bean的作用域,生命周期和注解,从创建到消亡的完整过程,例如人从出生到死亡的整个过程就是一个生命周期。本文将通过示例为大家详细讲讲,感兴趣的可以学习一下
    2022-07-07

最新评论