Is there any way to get the path environmental variable as a literal string instead of expanded?
i.e.
%systemroot%\System32;%systemroot%\;etc...
instead of
C:\Windows\System32;C:\Windows\;etc...
I've tried using
Environment.GetSystemVariable("Path");
But that gives me the expanded directories and I don't see anything else under Environment that will get me that.
Edit:
PathUnExpandEnvStrings
only works if the entire path is an environmental variable.
i.e.
C:\Windows\System32;C:\Windows;etc...
becomes
C:\Windows\System32;%systemroot%;etc...
using
Registry.GetValue(@"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment", "Path", null);
Still gets the values as C:\Windows\System32;C:\Windows;etc...
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.