获取文字系统变量路径

Get literal system variable path

有什么方法可以将路径环境变量作为文字字符串而不是扩展的吗?

%systemroot%\System32;%systemroot%\;etc...

而不是

C:\Windows\System32;C:\Windows\;etc...

我试过使用

Environment.GetSystemVariable("Path");

但这给了我扩展的目录,我在环境下看不到任何其他东西。

编辑:

PathUnExpandEnvStrings 仅当整个路径是环境变量时才有效。

C:\Windows\System32;C:\Windows;etc...

变成

C:\Windows\System32;%systemroot%;etc...

使用

Registry.GetValue(@"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment", "Path", null);

仍然得到 C:\Windows\System32;C:\Windows;etc...

的值

如果你走注册表路线,你可以通过 RegistryValueOptions.DoNotExpandEnvironmentNames to the RegistryKey.GetValue() instance method 来获取未扩展的路径...

using System;
using Microsoft.Win32;

namespace SO60725684
{
    class Program
    {
        static void Main()
        {
            const string environmentKeyPath = @"SYSTEM\CurrentControlSet\Control\Session Manager\Environment";
            const string valueName = "TEMP";

            using (RegistryKey environmentKey = Registry.LocalMachine.OpenSubKey(environmentKeyPath))
            {
                foreach (RegistryValueOptions options in Enum.GetValues(typeof(RegistryValueOptions)))
                {
                    object valueData = environmentKey.GetValue(valueName, "<default>", options);

                    Console.WriteLine($"{valueName} ({options}) = \"{valueData}\"");
                }
            }
        }
    }
}

这会打印...

Temp (None) = "C:\WINDOWS\TEMP"
Temp (DoNotExpandEnvironmentNames) = "%SystemRoot%\TEMP"

我使用 "TEMP" 变量只是为了它的值的简洁性,但它同样适用于 "Path".

如果你不想依赖环境变量的后备存储,还有一个Win32_Environment management class不扩展暴露值...

using System;
using System.Management;

namespace SO60725684
{
    class Program
    {
        static void Main()
        {
            string[] propertiesToDisplay = new string[] { "Name", "SystemVariable", "UserName", "VariableValue" };
            ObjectQuery query = new SelectQuery("Win32_Environment", "Name = 'TEMP'", propertiesToDisplay);

            using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(query))
            using (ManagementObjectCollection resultCollection = searcher.Get())
            {
                foreach (ManagementBaseObject resultInstance in resultCollection)
                {
                    PropertyDataCollection properties = resultInstance.Properties;

                    foreach (string propertyName in propertiesToDisplay)
                    {
                        PropertyData property = properties[propertyName];

                        Console.WriteLine($"{property.Name}: {property.Value}");
                    }
                    Console.WriteLine();
                }
            }
        }
    }
}

这会打印...

Name: TEMP
SystemVariable: True
UserName: <SYSTEM>
VariableValue: %SystemRoot%\TEMP

Name: TEMP
SystemVariable: False
UserName: NT AUTHORITY\SYSTEM
VariableValue: %USERPROFILE%\AppData\Local\Temp

Name: TEMP
SystemVariable: False
UserName: ComputerName\UserName
VariableValue: %USERPROFILE%\AppData\Local\Temp

如您所见,为多个用户定义变量时会得到多个结果,因此您需要对 SystemVariableUserName 属性进行进一步过滤以获得一个你要。