使用java批量写入环境变量

news2024/11/19 6:33:28

环境需求

  1. jdk版本:1.8
  2. 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;
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1500878.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一起来读李清照

当然先祝各位女生节日快乐&#x1f381;&#x1f381;啦​。​ 但是呢&#xff0c;今天&#xff0c;我们不聊技术&#xff0c;来聊点其他的。 大家都知道今天是三八妇女节&#xff0c;三八妇女节的是中国人的叫法&#xff0c;也叫国际妇女节。是为了纪念妇女权利的运动&#…

git fatal: detected dubious ownership in repository at ‘xxx‘ 彻底解决方法

前言 在 windows 重置后&#xff0c; git 仓库无法正常使用 git 的所有 命令&#xff0c;运行任何 git 命令&#xff0c;都会提示如下&#xff1a; $ git log fatal: detected dubious ownership in repository at D:/rk/rk3568/nanopi/uboot-rockchip D:/rk/rk3568/nanopi/u…

上班族真香副业:工资4500,靠steam游戏搬砖项目月入过w

steam游戏搬砖项目已经存在好多年了&#xff0c;这个项目比较冷门且能持续稳定盈利&#xff0c;是一个非常不错的项目。即使你没玩过steam游戏也没关系&#xff0c;这个steam游戏搬砖项目既不需要你会玩游戏&#xff0c;也不需要你懂英语。 steam游戏搬砖项目的盈利点在汇率差和…

什么才是数字化转型?

数字化转型是指企业或组织利用数字技术&#xff08;如云计算、大数据、人工智能、物联网等&#xff09;来改变其业务模式、运营流程、客户体验和企业文化&#xff0c;以提高效率、创新产品和服务、增强竞争力和创造新的增长机会。这一过程通常涉及对现有业务流程的重新设计&…

protobufjs使用教程,支持proto文件打包成typescript或javascript脚本

官方链接&#xff1a;https://docs.cocos.com/creator/manual/zh/scripting/modules/example.html 第一步&#xff0c;安装nodejs。&#xff08;自行安装&#xff09; 安装教程可参考 https://www.runoob.com/nodejs/nodejs-install-setup.html 第二步&#xff0c;创建cocos…

C++11_右值引用与移动语义

目录 1、左值的定义 1.1 左值引用 2、右值的定义 2.1 右值引用 3、右值与左值的使用区别 4、右值引用的意义 4.1 左值引用的短板 5、移动语义 5.1 移动构造 5.2 移动赋值 6、万能引用 6.1 右值的别名-左值化 6.2 完美转发 前言&#xff1a; 在C11之前就有了引…

浏览器一键重新发起请求

一、需求场景 在前端开发过程中&#xff0c;经常会需要重新请求后台进行代码调试&#xff0c;之前的常规方法是刷新浏览器页面或者点击页面进行交互&#xff0c;这样对多个请求的场景就很方便&#xff0c;但是往往很多时候我们只是单纯的想重新发起一个请求&#xff08;多个请求…

c++ 11 新特性 不同数据类型之间转换函数之const_cast

一.不同数据类型之间转换函数const_cast介绍 const_cast是C11中引入的一种类型转换操作符&#xff0c;用于修改类型的const或volatile属性。const_cast的主要用途是移除对象的常量性&#xff0c;它是唯一具有此能力的C风格的转型操作符。在C11中&#xff0c;const_cast可以完成…

YouTube Premium 会员氪金教程

前言 很多小伙伴喜欢看看YouTube但是有些需要会员才可以查看&#xff0c;会员可以免广告&#xff0c;根据个人需求选择是否需要开通 1、点击个人账号的头像&#xff0c;选择“购买内容和会员” 2、选择个人&#xff0c;点击免费试订&#xff0c;第一个月是免费&#xff0c;如…

智能驾驶规划控制理论学习08-自动驾驶控制模块(轨迹跟踪)

目录 一、基于几何的轨迹跟踪方法 1、基本思想 2、纯追踪 3、Stanly Method 二、PID控制器 三、LQR&#xff08;Linear Quadratic Regulator&#xff09; 1、基本思想 2、LQR解法 3、案例学习 基于LQR的路径跟踪 基于LQR的速度跟踪 4、MPC&#xff08;Mode…

【万题详解】DFS搜索专题合集(上)

专栏推荐 我的专栏——专栏链接 1.文章平均质量分 70分以上 2.以洛谷题为基础&#xff0c;解决C问题 3.有题目、讲解、思路、参考代码…… 4. 文章数&#xff1a;29 &#xff08;2024.3.8&#xff09; 课前C小程序&#xff08;脱控极域电子教室&#xff09; 这个图标相信…

‘老生常谈’ - 图书管理系统

在软件开发中&#xff0c;增、删、改、查这几个业务非常常见 增 基于axios从服务器拿到需要数据&#xff0c;进行渲染、封装&#xff0c;新增数据并不是一条一条渲染&#xff0c;而是整体重新渲染&#xff1b; 对于该系统新增数据&#xff1a;收集表单数据、提交服务器保存 -…

C++ 实战项目之 Boost 搜索引擎

项目地址&#xff1a;https://gitee.com/Vertas/boost-searcher-project 1. 项目背景 日常生活中我们使用过很多搜索引擎&#xff0c;比如百度&#xff0c;搜狗&#xff0c;360搜索等。我们今天是要实现一个像百度这样的搜索引擎嘛&#xff1f;那是不可能的&#xff0c;因为像…

听 GPT 讲 client-go 源代码 (24)

分享更多精彩内容&#xff0c;欢迎关注&#xff01; File: client-go/applyconfigurations/batch/v1/jobstatus.go 在client-go的applyconfigurations/batch/v1/jobstatus.go文件中&#xff0c;定义了与Job的状态相关的配置和操作。 文件中定义了以下几个结构体&#xff1a; Jo…

投标中项目组织结构的设置以及调整(样式表,多级列表)

投标中项目组织结构的设置以及调整&#xff08;样式表&#xff0c;多级列表&#xff09;&#xff1a; 投标项目中需要处理大规模的文字排版&#xff0c;就是需要用到样式表&#xff08;解决层级关系&#xff09;&#xff0c;多级列表&#xff08;解决自动编号的问题&#xff0…

WatiN——Web自动化测试(三)【弹出窗口处理】

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

Day25:安全开发-PHP应用文件管理模块包含上传遍历写入删除下载安全

目录 PHP文件操作安全 文件包含 文件删除 文件编辑 文件下载 云产品OSS存储对象去存储文件(泄漏安全) 思维导图 PHP知识点 功能&#xff1a;新闻列表&#xff0c;会员中心&#xff0c;资源下载&#xff0c;留言版&#xff0c;后台模块&#xff0c;模版引用&#xff0c;框…

7个实用的CSS技巧

1. First letter drop 首字母丢失 我们可以使用 :first-letter 来删除文本的第一个字母&#xff1a; p:first-letter {font-size: 200%;color: #8A2BE2; }:first-letter 选择器用于指定元素的首字母样式&#xff0c;它仅适用于块级元素。效果如下: codepen.io/OMGZui/pen/… …

Qt 5.14.2 网络编程揭秘:构建高效HTTP客户端与文件下载器

引言 在当今的软件开发世界中&#xff0c;网络通信已成为不可或缺的一部分。Qt&#xff0c;作为一个跨平台的C框架&#xff0c;为我们提供了强大的网络编程能力。本文将带你深入Qt的网络模块&#xff0c;探索如何使用QNetworkAccessManager、QNetworkRequest和QNetworkReply等核…

读《文明之光》第1册总结

人类几千年的文明史和地球的历史相比&#xff0c;实在是太短暂了&#xff0c;大约相当于几分钟和一年的关系。人类已经走过的路&#xff0c;相比今后要走的漫漫长路&#xff0c;只能算是刚刚起步。如果跳出一个个具体事件&#xff0c;站在历史的高度去看&#xff0c;我们会发现…