一、如何获取环境变量
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.
二、问题所在
由于环境变量是继承自父进程的,所以在进程启动后,再通过各种手段修改环境变量,不会对已经启动的进程环境变量产生影响。
那么,此时执行下述操作:
- 启动程序
- 通过系统属性修改环境变量
- 程序内通过
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;
}
咔~,问题解决。