吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 872|回复: 7
收起左侧

[求助] C# 有办法读出系统环境变量的原始值(含%xx%)么?而不是自作聪明把%xx%换成具体路径

[复制链接]
ilovecomputer66 发表于 2023-6-18 18:58
了解系统环境变量的朋友都知道,环境变量值中,也允许通过 %xx% 引用其他环境变量,从而非常灵活


但是我发现C# 提供的 获取系统环境变量的方法,有点自作聪明。


比如会用java的朋友都知道,当前主流JDK 版本为8和17,为了兼容新老项目,一个电脑要装2套环境。 那么java环境变量一般配置2个   %JAVA_8_HOME%  = jdk 8安装路径, %JAVA_17_HOME%  = jdk 17安装路径,然后%JAVA_HOME% = 刚才的%JAVA_8_HOME%或者%JAVA_17_HOME%
  系统Path中加入 %JAVA_HOME%


我这边需要用C#写一个图形化界面,管理java环境变量。实现一键创建、切换等等,这就需要能用C# 读取系统环境变量


但经过3天研究,我发现C#好像压根就做不到,读取原始的配置,比如我要读JAVA_HOME,期望返回是"%JAVA_8_HOME%"  这个原始配置字符串,而C# 总是给我返回  %JAVA_8_HOME%  对应的实际路径 C:\Program Files\Java\jdk1.8.0_301
这就太自作聪明了。我需要获取原始配置值,从而进行下一步操作。直接给我绝对路径,那没法搞了




——————————————
1、  Environment.GetEnvironmentVariable  方法获取的value 不是原始%xx%
2、用下面代码 一步步通过读取系统注册表,然后getvalue得到的仍旧不是原始%xx%
[C#] 纯文本查看 复制代码
public static RegistryKey OpenSysEnvironment()
        {
            RegistryKey regLocalMachine = Registry.LocalMachine;
            RegistryKey regSYSTEM = regLocalMachine.OpenSubKey("SYSTEM", true);//打开HKEY_LOCAL_MACHINE下的SYSTEM 
            RegistryKey regControlSet001 = regSYSTEM.OpenSubKey("ControlSet001", true);//打开ControlSet001 
            RegistryKey regControl = regControlSet001.OpenSubKey("Control", true);//打开Control 
            RegistryKey regManager = regControl.OpenSubKey("Session Manager", true);//打开Control 

            RegistryKey regEnvironment = regManager.OpenSubKey("Environment", true);
            return regEnvironment;
        }

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

NewType 发表于 2023-6-18 19:37
[Asm] 纯文本查看 复制代码
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment

[url]https://learn.microsoft.com/zh-cn/windows/win32/procthread/environment-variables[/url]
apull 发表于 2023-6-18 21:34
判断下获取到的值是否x:\开头,不是则继续找对应的环境变量。
pjy612 发表于 2023-6-18 22:18
本帖最后由 pjy612 于 2023-6-18 22:29 编辑

1.用 RegistryValueOptions.DoNotExpandEnvironmentNames
[C#] 纯文本查看 复制代码
static string GetRawEnvironmentVariableValue2(string variableName)
        {
            using (RegistryKey key = Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\Control\Session Manager\Environment"))
            {
                if (key != null)
                {
                    object value = key.GetValue(variableName, null, RegistryValueOptions.DoNotExpandEnvironmentNames);
                    if (value != null)
                    {
                        return value.ToString();
                    }
                }
            }
            return null;
        }

2.用底层API

[C#] 纯文本查看 复制代码
static string GetRawEnvironmentVariableValue(string variableName)
        {
            const int REG_EXPAND_SZ = 0x0002;
            const int KEY_QUERY_VALUE = 0x0001;
            const int ERROR_SUCCESS = 0;

            IntPtr hKey = IntPtr.Zero;
            int result = RegOpenKeyEx(RegistryHive.LocalMachine, @"SYSTEM\CurrentControlSet\Control\Session Manager\Environment", 0, KEY_QUERY_VALUE, out hKey);
            if (result != ERROR_SUCCESS)
            {
                return null;
            }

            StringBuilder buffer = new StringBuilder(1024);
            int bufferSize = buffer.Capacity * sizeof(char);
            result = RegQueryValueEx(hKey, variableName, IntPtr.Zero, out int lpType, buffer, ref bufferSize);
            RegCloseKey(hKey);
            if (result != ERROR_SUCCESS)
            {
                return null;
            }

            if (lpType == REG_EXPAND_SZ)
            {
                return buffer.ToString();
            }

            return null;
        }

        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern int RegOpenKeyEx(RegistryHive hKey, string lpSubKey, int ulOptions, int samDesired, out IntPtr phkResult);

        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern int RegCloseKey(IntPtr hKey);

        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern int RegQueryValueEx(IntPtr hKey, string lpValueName, IntPtr lpReserved, out int lpType, StringBuilder lpData, ref int lpcbData);

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
ilovecomputer66 + 1 + 1 感谢,非常完美

查看全部评分

 楼主| ilovecomputer66 发表于 2023-6-19 07:32
NewType 发表于 2023-6-18 19:37
[mw_shl_code=asm,true]HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environmen ...

早试过DllImport这个get函数,获取的也不是原始
 楼主| ilovecomputer66 发表于 2023-6-19 08:02
apull 发表于 2023-6-18 21:34
判断下获取到的值是否x:\开头,不是则继续找对应的环境变量。

恕我直言,自作聪明,学习下pjy612大佬的把
apull 发表于 2023-6-19 10:26
ilovecomputer66 发表于 2023-6-19 08:02
恕我直言,自作聪明,学习下pjy612大佬的把

只能给你回个呵呵了
 楼主| ilovecomputer66 发表于 2023-6-19 14:09
apull 发表于 2023-6-19 10:26
只能给你回个呵呵了

真可悲,大佬给了好方案,你不学习拉倒,就停留在各种垃圾方案,还觉得自己挺聪明上
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 23:02

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表