diff --git a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Windows.cs b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Windows.cs index f8da13f762a9d..3bcbb6eebc601 100644 --- a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Windows.cs +++ b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Windows.cs @@ -863,30 +863,23 @@ private void CreatePipe(out SafeFileHandle parentHandle, out SafeFileHandle chil private static string GetEnvironmentVariablesBlock(IDictionary sd) { - // get the keys - string[] keys = new string[sd.Count]; - sd.Keys.CopyTo(keys, 0); - - // sort both by the keys - // Windows 2000 requires the environment block to be sorted by the key - // It will first converting the case the strings and do ordinal comparison. + // https://docs.microsoft.com/en-us/windows/win32/procthread/changing-environment-variables + // "All strings in the environment block must be sorted alphabetically by name. The sort is + // case-insensitive, Unicode order, without regard to locale. Because the equal sign is a + // separator, it must not be used in the name of an environment variable." - // We do not use Array.Sort(keys, values, IComparer) since it is only supported - // in System.Runtime contract from 4.20.0.0 and Test.Net depends on System.Runtime 4.0.10.0 - // we workaround this by sorting only the keys and then lookup the values form the keys. + var keys = new string[sd.Count]; + sd.Keys.CopyTo(keys, 0); Array.Sort(keys, StringComparer.OrdinalIgnoreCase); - // create a list of null terminated "key=val" strings - StringBuilder stringBuff = new StringBuilder(); - for (int i = 0; i < sd.Count; ++i) + // Join the null-terminated "key=val\0" strings + var result = new StringBuilder(8 * keys.Length); + foreach (string key in keys) { - stringBuff.Append(keys[i]); - stringBuff.Append('='); - stringBuff.Append(sd[keys[i]]); - stringBuff.Append('\0'); + result.Append(key).Append('=').Append(sd[key]).Append('\0'); } - // an extra null at the end that indicates end of list will come from the string. - return stringBuff.ToString(); + + return result.ToString(); } } }