public static string ExpandEnvironmentVariables (string name)
{
if (name == null)
throw new ArgumentNullException ("name");
int off1 = name.IndexOf ('%');
if (off1 == -1)
return name;
int len = name.Length;
int off2 = 0;
if (off1 == len - 1 || (off2 = name.IndexOf ('%', off1 + 1)) == -1)
return name;
StringBuilder result = new StringBuilder ();
result.Append (name, 0, off1);
Hashtable tbl = null;
do {
string var = name.Substring (off1 + 1, off2 - off1 - 1);
string value = GetEnvironmentVariable (var);
if (value == null && Environment.IsRunningOnWindows) {
// On windows, env. vars. are case insensitive
if (tbl == null)
tbl = GetEnvironmentVariablesNoCase ();
value = tbl [var] as string;
}
// If value not found, add %FOO to stream,
// and use the closing % for the next iteration.
// If value found, expand it in place of %FOO%
if (value == null) {
result.Append ('%');
result.Append (var);
off2--;
} else {
result.Append (value);
}
int oldOff2 = off2;
off1 = name.IndexOf ('%', off2 + 1);
// If no % found for off1, don't look for one for off2
off2 = (off1 == -1 || off2 > len-1)? -1 :name.IndexOf ('%', off1 + 1);
// textLen is the length of text between the closing % of current iteration
// and the starting % of the next iteration if any. This text is added to output
int textLen;
// If no new % found, use all the remaining text
if (off1 == -1 || off2 == -1)
textLen = len - oldOff2 - 1;
// If value found in current iteration, use text after current closing % and next %
else if(value != null)
textLen = off1 - oldOff2 - 1;
// If value not found in current iteration, but a % was found for next iteration,
// use text from current closing % to the next %.
else
textLen = off1 - oldOff2;
if(off1 >= oldOff2 || off1 == -1)
result.Append (name, oldOff2+1, textLen);
} while (off2 > -1 && off2 < len);
return result.ToString ();
}