轻聆月下
轻聆月下
发布于 2024-03-24 / 17 阅读
0
0

使用C#在Windows环境实时获取新的环境变量

一、如何获取环境变量

C# 中可以通过这个函数获取环境变量:Environment.GetEnvironmentVariables Method

示例如下:

// Sample for the Environment.GetEnvironmentVariables method
using System;
using System.Collections;

class Sample
{
    public static void Main()
    {
       Console.WriteLine();
       Console.WriteLine("GetEnvironmentVariables: ");
       foreach (DictionaryEntry de in Environment.GetEnvironmentVariables())
           Console.WriteLine("  {0} = {1}", de.Key, de.Value);
    }
}
// Output from the example is not shown, since it is:
//    Lengthy.
//    Specific to the machine on which the example is run.
//    May reveal information that should remain secure.

二、问题所在

由于环境变量是继承自父进程的,所以在进程启动后,再通过各种手段修改环境变量,不会对已经启动的进程环境变量产生影响。

那么,此时执行下述操作:

  1. 启动程序
  2. 通过系统属性修改环境变量
  3. 程序内通过 GetEnvironmentVariables 获取环境变量

我们会发现 GetEnvironmentVariables 并不能获取修改后的环境变量。此问题是因为环境变量的继承关系决定的。

三、解决问题

如果我们既不能重启程序,又想要获取最新的环境变量应该如何处理呢?答案是:通过注册表。

实际上Windows系统的环境变量是写在注册表内的,注册表内的环境变量并不受进程的继承关系影响。

用户的环境变量存在于注册表的:\HKEY_CURRENT_USER\Environment

系统环境变量存在于注册表的:\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment

我们在C#代码中可以通过下述代码遍历环境变量,而不受环境变量的继承影响,从而拿到实时最新的环境变量:

public Dictionary<string,string> GetAllEnv()
{
    var result = new Dictionary<string,string>();
    RegistryKey keyU = Registry.CurrentUser.OpenSubKey("Environment");
    keyU.GetValueNames().ToList().ForEach(name => {
        result.Add(name, keyU.GetValue(name).ToString());
    });
    keyU.Close();
    RegistryKey key = Registry.LocalMachine.OpenSubKey("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment");
    key.GetValueNames().ToList().ForEach(name => {
        result.Add(name, key.GetValue(name).ToString());
    });
    key.Close();
    return result;
}

咔~,问题解决。


评论