If you go the registry route you can pass RegistryValueOptions.DoNotExpandEnvironmentNames
to the RegistryKey.GetValue()
instance method to get the unexpanded path...
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}\"");
}
}
}
}
}
This prints...
Temp (None) = "C:\WINDOWS\TEMP"
Temp (DoNotExpandEnvironmentNames) = "%SystemRoot%\TEMP"
I'm using the "TEMP"
variable just for the brevity of its value, but it works just as well for "Path"
.
If you don't want to rely on the backing storage of an environment variable, there is also a Win32_Environment
management class that exposes the value without expansion...
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();
}
}
}
}
}
This prints...
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
As you can see, you get multiple results when the variable is defined for multiple users, so you'll need to do further filtering on the SystemVariable
and UserName
properties to get the one you want.