使用java批量写入环境变量

环境需求

  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;
    }

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java - Spring MVC 实现跨域资源 CORS 请求

据我所知道的是有三种方式&#xff1a;Tomcat 配置、拦截器设置响应头和使用 Spring MVC 4.2。 设置 Tomcat 这种方式就是引用别人封装好的两个 jar 包&#xff0c;配置一下web.xml就行了。我也并不推荐&#xff0c;这里放两个我在网上找到的配置相关文章&#xff0c;感兴趣可…

更快更强,Claude 3全面超越GPT4,能归纳15万单词

ChatGPT4和Gemini Ultra被Claude 3 AI模型超越了&#xff1f; 3月4日周一&#xff0c;人工智能公司Anthropic推出了Claude 3系列AI模型和新型聊天机器人&#xff0c;其中包括Opus、Sonnet和Haiku三种模型&#xff0c;该公司声称&#xff0c;这是迄今为止它们开发的最快速、最强…

【论文阅读】DeepLab:语义图像分割与深度卷积网络,自然卷积,和完全连接的crf

【论文阅读】DeepLab:语义图像分割与深度卷积网络&#xff0c;自然卷积&#xff0c;和完全连接的crf 文章目录 【论文阅读】DeepLab:语义图像分割与深度卷积网络&#xff0c;自然卷积&#xff0c;和完全连接的crf一、介绍二、联系工作三、方法3.1 整体结构3.2 使用空间金字塔池…

Stable Diffusion 提示词语法(Prompt)

本文收录于《AI绘画从入门到精通》专栏&#xff0c;专栏总目录&#xff1a;点这里。 大家好&#xff0c;我是水滴~~ 本篇文章主要讲述 Stable Diffusion 提示词语法&#xff0c;主要包括&#xff1a;提示词的概念、提示词的长度、权重、分步绘制、交替绘制、组合绘制等&#x…

ORA/GSA -- 学习记录

brief over-representation analysis(ORA),过表“达”分析&#xff0c;就是我们做多分组的RNAseq数据解析后会得到一些差异表达的gene&#xff0c;有些时候是单独拿出一个差异gene去解释表型&#xff0c;缺点是欠缺证据力度。有些人就把一些相关的差异gene放在一块儿解释&…

leetcode 热题 100_最大子数组和

题解一&#xff1a; 动态规划&#xff1a;这是一道经典的动态规划题。维护一个dp数组&#xff0c;dp[i]表示0~i组成的数组的最大子数组和。当数组长度为1时&#xff0c;最大和连续子数组是它本身&#xff0c;也就是dp[i]nums[i]。当数组长度每增加1时&#xff0c;最大和连续子数…

精准获客、优化体验,Xinstall数据自动分析全搞定

在移动互联网时代&#xff0c;App已经成为了我们生活中不可或缺的一部分。然而&#xff0c;对于App开发者来说&#xff0c;如何有效地评估渠道效果、精准获客以及优化用户体验&#xff0c;一直是一个令人头疼的问题。幸运的是&#xff0c;Xinstall作为一款一站式App全渠道统计服…

YOLOv9: Learning What You Want to Learn Using Programmable Gradient Information

paper: https://arxiv.org/abs/2402.13616 code YOLOv9: Learning What You Want to Learn Using Programmable Gradient Information 一、引言部分二、问题分析2.1 信息瓶颈原理2.2 可逆函数 三、本文方法3.1 可编程梯度信息 四、实验4.1消融实验部分 今天的深度学习方法关注的…

Ajax、Axios、Vue、Element与其案例

目录 一.Ajax 二.Axios 三.Vue 四.Element 五.增删改查案例 一.依赖&#xff1a;数据库&#xff0c;mybatis&#xff0c;servlet&#xff0c;json-对象转换器 二.资源&#xff1a;elementvueaxios 三.pojo 四.mapper.xml与mapper接口 五.service 六.servlet 七.html页…

产品展示型wordpress外贸网站模板

孕婴产品wordpress外贸网站模板 吸奶器、待产包、孕妇枕头、护理垫、纸尿裤、孕妇装、孕婴产品wordpress外贸网站模板。 https://www.jianzhanpress.com/?p4112 床品毛巾wordpress独立站模板 床单、被套、毛巾、抱枕、靠垫、围巾、布艺、枕头、乳胶枕、四件套、浴巾wordpre…

请说明Vue中的异步组件加载

Vue中的异步组件加载是指当页面需要渲染某个组件时&#xff0c;可以在需要时再去加载这个组件&#xff0c;而不是在页面初始化的时候就将所有组件一次性加载进来。这种方式能够有效降低页面的初始加载时间&#xff0c;提升用户体验。 在Vue中&#xff0c;我们可以使用import函…

Dgraph 入门教程三(linux本地部署)

上一章中&#xff0c;我们用的官方的Clound操作的&#xff0c;怎么在本地部署一套Dgraph呢。这一章将做详细介绍。安装有好几种方式&#xff0c;最简单的就是联网部署。因为项目需要&#xff0c;这里先不介绍和测试线上部署了&#xff0c;只介绍离线部署。 1、下载安装包 Rel…

flask 数据库迁移报错 Error: No such command ‘db‘.

初学FLASK&#xff0c;使用pycharm的terminal 启动&#xff0c;实现数据库迁移 文件结构 项目启动文件不在一级目录pycharm>terminal启动 由于自己初入 python flask 很多东西并不懂&#xff0c;只能依葫芦画瓢&#xff0c;使用如下命令,输入完第一行命令执行没有任何错误…

Android Termux系统安装openssh实现公网使用SFTP远程访问

文章目录 1. 安装openSSH2. 安装cpolar3. 远程SFTP连接配置4. 远程SFTP访问4. 配置固定远程连接地址 SFTP&#xff08;SSH File Transfer Protocol&#xff09;是一种基于SSH&#xff08;Secure Shell&#xff09;安全协议的文件传输协议。与FTP协议相比&#xff0c;SFTP使用了…

力扣写法题:最后一个单词的长度

如果最后一个单词后有空格可以采用以下的写 int lengthOfLastWord(char* s) {int count0,flag0;int i(strlen(s)-1);while(i>0){if(s[i]! ) flag1;if(flag1) {if(s[i] ) break;else count;}i--;}return count; }

IAR全面支持小华全系芯片,强化工控及汽车MCU生态圈

IAR Embedded Workbench for Arm已全面支持小华半导体系列芯片&#xff0c;加速高端工控MCU和车用MCU应用的安全开发 嵌入式开发软件和服务的全球领导者IAR与小华半导体有限公司&#xff08;以下简称“小华半导体”&#xff09;联合宣布&#xff0c;IAR Embedded Workbench fo…

STM32CubeMX学习笔记14 ---SPI总线

1. 简介 1.1 SPI总线介绍 SPI 是英语Serial Peripheral interface的缩写&#xff0c;顾名思义就是串行外围设备接口。是Motorola(摩托罗拉)首先在其MC68HCXX系列处理器上定义的。 SPI&#xff0c;是一种高速的&#xff0c;全双工&#xff0c;同步的通信总线&#xff0c;并且在…

如何把网页调用变为代码调用

1.背景 最近有一个需求&#xff0c;猜测一段十六进制流的校验方式&#xff0c;挨个尝试非常耗时&#xff0c;需要写代码&#xff0c;调用网页上的功能。 2.解决方案 可以使用Python的 requests 库来发起HTTP请求&#xff0c;并通过POST请求将数据发送给服务器进行计算CRC校验和…

类和对象周边知识

再谈构造函数 前几期我们把六个默认成员函数一一说明后&#xff0c;构造函数还有一些周边知识。 初始化列表 我们在没有了解初始化列表的时候一般都是使用构造函数初始化或者在声明哪里给予缺省值&#xff0c;那么为什么好药存在初始化列表呢&#xff1f;是因为①.有些值必须…

Java后台面试相关知识点解析

文章目录 JavaJava中四种引用类型及使用场景集合HashMap源码及扩容策略HashMap死循环问题ConcurrentHashMap与HashtableConCurrentHashMap 1.8 相比 1.7 判断单链表是否有环&#xff0c;并且找出环的入口IO线程池线程池的几种创建方式判断线程是否可以回收线程池的7大核心参数线…