Get the real values of environment variables on a

2019-04-26 14:56发布

问题:

I'm trying to get the actual values of environment variables.
This is what I have so far:

string query = string.Format("Select VariableValue From Win32_Environment Where Name = '{0}'", variableName);

using (var searcher = new ManagementObjectSearcher(query))
using (ManagementObject result = searcher.Get().Cast<ManagementObject>().FirstOrDefault())
{
    if (result != null)
    return Convert.ToString(result["VariableValue"]);
}

That works, but here's the problem: passing 'windir' as name gets '%SystemRoot%' as value. What I really want is the actual path, i.e. 'C:\Windows'.

I tried using recursion to get the value of 'SystemRoot' but no matches were found.

How can I make sure that the real values get returned?
Thx!

回答1:

For system path variables (like %SystemRoot%) there's no convenient way.

You have to look for these values yourself by reading the corresponding registry values. Heres' a (not complete) list of some of these system variables:

  • %SystemRoot%:

    HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SystemRoot
    or

    select windowsdirectory from Win32_OperatingSystem
  • %SystemDrive% can be determined by examining %SystemRoot%

Variables like %AppData% are user dependent and found under

HKEY_USERS\<user SID>\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders\AppData



回答2:

I know it's creative at best but this seems to be the simplest solution:
Too much overhead perhaps?

        using (var process = new Process())
        {
            process.StartInfo.FileName = @"C:\PsTools\PsExec.exe";
            process.StartInfo.Arguments = @"\\machineName cmd /c echo " + environmentVar;
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.CreateNoWindow = true;
            process.StartInfo.RedirectStandardOutput = true;
            process.Start();
            return process.StandardOutput.ReadToEnd();
        }


回答3:

You can't use Win32_Environment for this, but you can use remote registry.

RegistryKey environmentKey = RegistryKey.OpenRemoteBaseKey(
      RegistryHive.LocalMachine, "\\server");
RegistryKey key = environmentKey.OpenSubKey(
      @"SYSTEM\CurrentControlSet\Control\Session Manager\Environment", false);
string value = (string)key.GetValue("System");


回答4:

use Environment.GetFolderPath(Environment.SpecialFolder.System)