diff --git a/src/System.Runtime.Extensions/System.Runtime.Extensions.sln b/src/System.Runtime.Extensions/System.Runtime.Extensions.sln
index 54d55b2bb662..a56140ab8633 100644
--- a/src/System.Runtime.Extensions/System.Runtime.Extensions.sln
+++ b/src/System.Runtime.Extensions/System.Runtime.Extensions.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
-VisualStudioVersion = 14.0.23107.0
+VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Runtime.Extensions", "src\System.Runtime.Extensions.csproj", "{845D2B72-D8A4-42E5-9BE9-17639EC4FC1A}"
EndProject
@@ -135,6 +135,66 @@ Global
{9F312D76-9AF1-4E90-B3B0-815A1EC6C346}.Windows_Debug|Any CPU.Build.0 = Debug|Any CPU
{9F312D76-9AF1-4E90-B3B0-815A1EC6C346}.Windows_Release|Any CPU.ActiveCfg = Release|Any CPU
{9F312D76-9AF1-4E90-B3B0-815A1EC6C346}.Windows_Release|Any CPU.Build.0 = Release|Any CPU
+ {24BCEC6B-B9D2-47BC-9D66-725BD6B526FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {24BCEC6B-B9D2-47BC-9D66-725BD6B526FA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {24BCEC6B-B9D2-47BC-9D66-725BD6B526FA}.net46_Debug|Any CPU.ActiveCfg = net46_Debug|Any CPU
+ {24BCEC6B-B9D2-47BC-9D66-725BD6B526FA}.net46_Debug|Any CPU.Build.0 = net46_Debug|Any CPU
+ {24BCEC6B-B9D2-47BC-9D66-725BD6B526FA}.net46_Release|Any CPU.ActiveCfg = net46_Release|Any CPU
+ {24BCEC6B-B9D2-47BC-9D66-725BD6B526FA}.net46_Release|Any CPU.Build.0 = net46_Release|Any CPU
+ {24BCEC6B-B9D2-47BC-9D66-725BD6B526FA}.netstandard1.7_Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {24BCEC6B-B9D2-47BC-9D66-725BD6B526FA}.netstandard1.7_Debug|Any CPU.Build.0 = Debug|Any CPU
+ {24BCEC6B-B9D2-47BC-9D66-725BD6B526FA}.netstandard1.7_Release|Any CPU.ActiveCfg = Release|Any CPU
+ {24BCEC6B-B9D2-47BC-9D66-725BD6B526FA}.netstandard1.7_Release|Any CPU.Build.0 = Release|Any CPU
+ {24BCEC6B-B9D2-47BC-9D66-725BD6B526FA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {24BCEC6B-B9D2-47BC-9D66-725BD6B526FA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {24BCEC6B-B9D2-47BC-9D66-725BD6B526FA}.Unix_Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {24BCEC6B-B9D2-47BC-9D66-725BD6B526FA}.Unix_Debug|Any CPU.Build.0 = Debug|Any CPU
+ {24BCEC6B-B9D2-47BC-9D66-725BD6B526FA}.Unix_Release|Any CPU.ActiveCfg = Release|Any CPU
+ {24BCEC6B-B9D2-47BC-9D66-725BD6B526FA}.Unix_Release|Any CPU.Build.0 = Release|Any CPU
+ {24BCEC6B-B9D2-47BC-9D66-725BD6B526FA}.Windows_Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {24BCEC6B-B9D2-47BC-9D66-725BD6B526FA}.Windows_Debug|Any CPU.Build.0 = Debug|Any CPU
+ {24BCEC6B-B9D2-47BC-9D66-725BD6B526FA}.Windows_Release|Any CPU.ActiveCfg = Release|Any CPU
+ {24BCEC6B-B9D2-47BC-9D66-725BD6B526FA}.Windows_Release|Any CPU.Build.0 = Release|Any CPU
+ {AD83807C-8BE5-4F27-85DF-9793613233E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AD83807C-8BE5-4F27-85DF-9793613233E1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AD83807C-8BE5-4F27-85DF-9793613233E1}.net46_Debug|Any CPU.ActiveCfg = net46_Debug|Any CPU
+ {AD83807C-8BE5-4F27-85DF-9793613233E1}.net46_Debug|Any CPU.Build.0 = net46_Debug|Any CPU
+ {AD83807C-8BE5-4F27-85DF-9793613233E1}.net46_Release|Any CPU.ActiveCfg = net46_Release|Any CPU
+ {AD83807C-8BE5-4F27-85DF-9793613233E1}.net46_Release|Any CPU.Build.0 = net46_Release|Any CPU
+ {AD83807C-8BE5-4F27-85DF-9793613233E1}.netstandard1.7_Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AD83807C-8BE5-4F27-85DF-9793613233E1}.netstandard1.7_Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AD83807C-8BE5-4F27-85DF-9793613233E1}.netstandard1.7_Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AD83807C-8BE5-4F27-85DF-9793613233E1}.netstandard1.7_Release|Any CPU.Build.0 = Release|Any CPU
+ {AD83807C-8BE5-4F27-85DF-9793613233E1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AD83807C-8BE5-4F27-85DF-9793613233E1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AD83807C-8BE5-4F27-85DF-9793613233E1}.Unix_Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AD83807C-8BE5-4F27-85DF-9793613233E1}.Unix_Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AD83807C-8BE5-4F27-85DF-9793613233E1}.Unix_Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AD83807C-8BE5-4F27-85DF-9793613233E1}.Unix_Release|Any CPU.Build.0 = Release|Any CPU
+ {AD83807C-8BE5-4F27-85DF-9793613233E1}.Windows_Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AD83807C-8BE5-4F27-85DF-9793613233E1}.Windows_Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AD83807C-8BE5-4F27-85DF-9793613233E1}.Windows_Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AD83807C-8BE5-4F27-85DF-9793613233E1}.Windows_Release|Any CPU.Build.0 = Release|Any CPU
+ {C44B33E3-F89F-40B9-B353-D380C1524988}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C44B33E3-F89F-40B9-B353-D380C1524988}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C44B33E3-F89F-40B9-B353-D380C1524988}.net46_Debug|Any CPU.ActiveCfg = net46_Debug|Any CPU
+ {C44B33E3-F89F-40B9-B353-D380C1524988}.net46_Debug|Any CPU.Build.0 = net46_Debug|Any CPU
+ {C44B33E3-F89F-40B9-B353-D380C1524988}.net46_Release|Any CPU.ActiveCfg = net46_Release|Any CPU
+ {C44B33E3-F89F-40B9-B353-D380C1524988}.net46_Release|Any CPU.Build.0 = net46_Release|Any CPU
+ {C44B33E3-F89F-40B9-B353-D380C1524988}.netstandard1.7_Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C44B33E3-F89F-40B9-B353-D380C1524988}.netstandard1.7_Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C44B33E3-F89F-40B9-B353-D380C1524988}.netstandard1.7_Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C44B33E3-F89F-40B9-B353-D380C1524988}.netstandard1.7_Release|Any CPU.Build.0 = Release|Any CPU
+ {C44B33E3-F89F-40B9-B353-D380C1524988}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C44B33E3-F89F-40B9-B353-D380C1524988}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C44B33E3-F89F-40B9-B353-D380C1524988}.Unix_Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C44B33E3-F89F-40B9-B353-D380C1524988}.Unix_Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C44B33E3-F89F-40B9-B353-D380C1524988}.Unix_Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C44B33E3-F89F-40B9-B353-D380C1524988}.Unix_Release|Any CPU.Build.0 = Release|Any CPU
+ {C44B33E3-F89F-40B9-B353-D380C1524988}.Windows_Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C44B33E3-F89F-40B9-B353-D380C1524988}.Windows_Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C44B33E3-F89F-40B9-B353-D380C1524988}.Windows_Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C44B33E3-F89F-40B9-B353-D380C1524988}.Windows_Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/src/System.Runtime.Extensions/src/System.Runtime.Extensions.csproj b/src/System.Runtime.Extensions/src/System.Runtime.Extensions.csproj
index 418e4d5bef69..58d6d9b747af 100644
--- a/src/System.Runtime.Extensions/src/System.Runtime.Extensions.csproj
+++ b/src/System.Runtime.Extensions/src/System.Runtime.Extensions.csproj
@@ -55,13 +55,11 @@
-
-
@@ -140,8 +138,6 @@
-
-
Common\System\IO\Win32Marshal.cs
@@ -160,15 +156,9 @@
Common\Interop\Windows\kernel32\Interop.GetCurrentDirectory.cs
-
- Common\Interop\Windows\kernel32\Interop.GetFullPathNameW.cs
-
Common\Interop\Windows\kernel32\Interop.GetLongPathName.cs
-
- Common\Interop\Windows\kernel32\Interop.GetLongPathNameW.cs
-
Common\Interop\Windows\kernel32\Interop.GetSystemInfo.cs
@@ -196,20 +186,14 @@
Common\System\IO\PathInternal.Windows.cs
-
- Common\System\IO\PathInternal.Windows.StringBuffer.cs
-
+
+
+
+
-
+
-
-
- Common\Interop\Windows\BCrypt\Interop.BCryptGenRandom.cs
-
-
- Common\Interop\Windows\BCrypt\Interop.NTSTATUS.cs
-
Common\Interop\Windows\kernel32\Interop.EnvironmentVariables.cs
@@ -334,7 +318,6 @@
-
Common\Interop\OSX\Interop.Libraries.cs
@@ -420,12 +403,25 @@
+
+
+
+
+
+
+ Common\System\IO\PathInternal.Windows.StringBuffer.cs
+
+
+ Common\Interop\Windows\kernel32\Interop.GetFullPathNameW.cs
+
+
+ Common\Interop\Windows\kernel32\Interop.GetLongPathNameW.cs
+
-
@@ -472,4 +468,4 @@
-
+
\ No newline at end of file
diff --git a/src/System.Runtime.Extensions/src/System/Environment.Uap.cs b/src/System.Runtime.Extensions/src/System/Environment.Uap.cs
index 8acecaeb64c1..226ce363ca5e 100644
--- a/src/System.Runtime.Extensions/src/System/Environment.Uap.cs
+++ b/src/System.Runtime.Extensions/src/System/Environment.Uap.cs
@@ -58,5 +58,104 @@ private static void SetEnvironmentVariableCore(string variable, string value, En
public static string UserName { get { throw new PlatformNotSupportedException(); } }
public static string UserDomainName { get { throw new PlatformNotSupportedException(); } }
+
+
+ public static string GetEnvironmentVariable(string variable)
+ {
+ if (variable == null)
+ {
+ throw new ArgumentNullException(nameof(variable));
+ }
+
+ // separated from the EnvironmentVariableTarget overload to help with tree shaking in common case
+ return GetEnvironmentVariableCore(variable);
+ }
+
+ public static string GetEnvironmentVariable(string variable, EnvironmentVariableTarget target)
+ {
+ if (variable == null)
+ {
+ throw new ArgumentNullException(nameof(variable));
+ }
+
+ ValidateTarget(target);
+
+ return GetEnvironmentVariableCore(variable, target);
+ }
+
+ public static IDictionary GetEnvironmentVariables()
+ {
+ // separated from the EnvironmentVariableTarget overload to help with tree shaking in common case
+ return GetEnvironmentVariablesCore();
+ }
+
+ public static IDictionary GetEnvironmentVariables(EnvironmentVariableTarget target)
+ {
+ ValidateTarget(target);
+
+ return GetEnvironmentVariablesCore(target);
+ }
+
+ public static void SetEnvironmentVariable(string variable, string value)
+ {
+ ValidateVariableAndValue(variable, ref value);
+
+ // separated from the EnvironmentVariableTarget overload to help with tree shaking in common case
+ SetEnvironmentVariableCore(variable, value);
+ }
+
+ public static void SetEnvironmentVariable(string variable, string value, EnvironmentVariableTarget target)
+ {
+ ValidateVariableAndValue(variable, ref value);
+ ValidateTarget(target);
+
+ SetEnvironmentVariableCore(variable, value, target);
+ }
+
+ private static void ValidateVariableAndValue(string variable, ref string value)
+ {
+ const int MaxEnvVariableValueLength = 32767;
+
+ if (variable == null)
+ {
+ throw new ArgumentNullException(nameof(variable));
+ }
+ if (variable.Length == 0)
+ {
+ throw new ArgumentException(SR.Argument_StringZeroLength, nameof(variable));
+ }
+ if (variable[0] == '\0')
+ {
+ throw new ArgumentException(SR.Argument_StringFirstCharIsZero, nameof(variable));
+ }
+ if (variable.Length >= MaxEnvVariableValueLength)
+ {
+ throw new ArgumentException(SR.Argument_LongEnvVarValue, nameof(variable));
+ }
+ if (variable.IndexOf('=') != -1)
+ {
+ throw new ArgumentException(SR.Argument_IllegalEnvVarName, nameof(variable));
+ }
+
+ if (string.IsNullOrEmpty(value) || value[0] == '\0')
+ {
+ // Explicitly null out value if it's empty
+ value = null;
+ }
+ else if (value.Length >= MaxEnvVariableValueLength)
+ {
+ throw new ArgumentException(SR.Argument_LongEnvVarValue, nameof(value));
+ }
+ }
+
+ private static void ValidateTarget(EnvironmentVariableTarget target)
+ {
+ if (target != EnvironmentVariableTarget.Process &&
+ target != EnvironmentVariableTarget.Machine &&
+ target != EnvironmentVariableTarget.User)
+ {
+ throw new ArgumentOutOfRangeException(nameof(target), target, SR.Format(SR.Arg_EnumIllegalVal, target));
+ }
+ }
}
}
diff --git a/src/System.Runtime.Extensions/src/System/Environment.Unix.cs b/src/System.Runtime.Extensions/src/System/Environment.Unix.cs
index 449d201f4ebf..3d01bfa839b5 100644
--- a/src/System.Runtime.Extensions/src/System/Environment.Unix.cs
+++ b/src/System.Runtime.Extensions/src/System/Environment.Unix.cs
@@ -16,28 +16,6 @@ namespace System
{
public static partial class Environment
{
- private static readonly unsafe Lazy> s_environ = new Lazy>(() =>
- {
- var results = new LowLevelDictionary();
- byte** environ = Interop.Sys.GetEnviron();
- if (environ != null)
- {
- for (byte** ptr = environ; *ptr != null; ptr++)
- {
- string entry = Marshal.PtrToStringAnsi((IntPtr)(*ptr));
- int equalsPos = entry.IndexOf('=');
- if (equalsPos != -1)
- {
- results.Add(entry.Substring(0, equalsPos), entry.Substring(equalsPos + 1));
- }
- else
- {
- results.Add(entry, string.Empty);
- }
- }
- }
- return results;
- });
internal static readonly bool IsMac = Interop.Sys.GetUnixName() == "OSX";
private static Func> s_fileReadLines;
private static Action s_directoryCreateDirectory;
@@ -76,45 +54,6 @@ private static string ExpandEnvironmentVariablesCore(string name)
return StringBuilderCache.GetStringAndRelease(result);
}
- private static string GetEnvironmentVariableCore(string variable)
- {
- // Ensure variable doesn't include a null char
- int nullEnd = variable.IndexOf('\0');
- if (nullEnd != -1)
- {
- variable = variable.Substring(0, nullEnd);
- }
-
- // Get the value of the variable
- lock (s_environ)
- {
- string value;
- return s_environ.Value.TryGetValue(variable, out value) ? value : null;
- }
- }
-
- private static string GetEnvironmentVariableCore(string variable, EnvironmentVariableTarget target)
- {
- return target == EnvironmentVariableTarget.Process ?
- GetEnvironmentVariableCore(variable) :
- null;
- }
-
- private static IDictionary GetEnvironmentVariablesCore()
- {
- lock (s_environ)
- {
- return s_environ.Value.Clone();
- }
- }
-
- private static IDictionary GetEnvironmentVariablesCore(EnvironmentVariableTarget target)
- {
- return target == EnvironmentVariableTarget.Process ?
- GetEnvironmentVariablesCore() :
- new LowLevelDictionary();
- }
-
private static string GetFolderPathCore(SpecialFolder folder, SpecialFolderOption option)
{
// Get the path for the SpecialFolder
@@ -419,50 +358,6 @@ private static int FindAndParseNextNumber(string text, ref int pos)
public static int ProcessorCount => (int)Interop.Sys.SysConf(Interop.Sys.SysConfName._SC_NPROCESSORS_ONLN);
- private static void SetEnvironmentVariableCore(string variable, string value)
- {
- int nullEnd;
-
- // Ensure variable doesn't include a null char
- nullEnd = variable.IndexOf('\0');
- if (nullEnd != -1)
- {
- variable = variable.Substring(0, nullEnd);
- }
-
- // Ensure value doesn't include a null char
- if (value != null)
- {
- nullEnd = value.IndexOf('\0');
- if (nullEnd != -1)
- {
- value = value.Substring(0, nullEnd);
- }
- }
-
- lock (s_environ)
- {
- // Remove the entry if the value is null, otherwise add/overwrite it
- if (value == null)
- {
- s_environ.Value.Remove(variable);
- }
- else
- {
- s_environ.Value[variable] = value;
- }
- }
- }
-
- private static void SetEnvironmentVariableCore(string variable, string value, EnvironmentVariableTarget target)
- {
- if (target == EnvironmentVariableTarget.Process)
- {
- SetEnvironmentVariableCore(variable, value);
- }
- // other targets ignored
- }
-
public static string SystemDirectory => GetFolderPathCore(SpecialFolder.System, SpecialFolderOption.None);
public static int SystemPageSize => (int)Interop.Sys.SysConf(Interop.Sys.SysConfName._SC_PAGESIZE);
diff --git a/src/System.Runtime.Extensions/src/System/Environment.Win32.Unix.cs b/src/System.Runtime.Extensions/src/System/Environment.Win32.Unix.cs
new file mode 100644
index 000000000000..272e370949cd
--- /dev/null
+++ b/src/System.Runtime.Extensions/src/System/Environment.Win32.Unix.cs
@@ -0,0 +1,42 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Internal.Runtime.Augments;
+using System.Collections;
+
+namespace System
+{
+ public static partial class Environment
+ {
+ public static string GetEnvironmentVariable(string variable)
+ {
+ return EnvironmentAugments.GetEnvironmentVariable(variable);
+ }
+
+ public static string GetEnvironmentVariable(string variable, EnvironmentVariableTarget target)
+ {
+ return EnvironmentAugments.GetEnvironmentVariable(variable, target);
+ }
+
+ public static IDictionary GetEnvironmentVariables()
+ {
+ return EnvironmentAugments.GetEnvironmentVariables();
+ }
+
+ public static IDictionary GetEnvironmentVariables(EnvironmentVariableTarget target)
+ {
+ return EnvironmentAugments.GetEnvironmentVariables(target);
+ }
+
+ public static void SetEnvironmentVariable(string variable, string value)
+ {
+ EnvironmentAugments.SetEnvironmentVariable(variable, value);
+ }
+
+ public static void SetEnvironmentVariable(string variable, string value, EnvironmentVariableTarget target)
+ {
+ EnvironmentAugments.SetEnvironmentVariable(variable, value, target);
+ }
+ }
+}
diff --git a/src/System.Runtime.Extensions/src/System/Environment.Win32.cs b/src/System.Runtime.Extensions/src/System/Environment.Win32.cs
index b653a7cb415f..ffdf5218d494 100644
--- a/src/System.Runtime.Extensions/src/System/Environment.Win32.cs
+++ b/src/System.Runtime.Extensions/src/System/Environment.Win32.cs
@@ -47,165 +47,6 @@ private static string ExpandEnvironmentVariablesCore(string name)
return StringBuilderCache.GetStringAndRelease(result);
}
- private static string GetEnvironmentVariableCore(string variable)
- {
- StringBuilder sb = StringBuilderCache.Acquire(128); // a somewhat reasonable default size
- int requiredSize = Interop.Kernel32.GetEnvironmentVariableW(variable, sb, sb.Capacity);
- if (requiredSize == 0 && Marshal.GetLastWin32Error() == Interop.Errors.ERROR_ENVVAR_NOT_FOUND)
- {
- StringBuilderCache.Release(sb);
- return null;
- }
-
- while (requiredSize > sb.Capacity)
- {
- sb.Capacity = requiredSize;
- sb.Length = 0;
- requiredSize = Interop.Kernel32.GetEnvironmentVariableW(variable, sb, sb.Capacity);
- }
-
- return StringBuilderCache.GetStringAndRelease(sb);
- }
-
- private static string GetEnvironmentVariableCore(string variable, EnvironmentVariableTarget target)
- {
- if (target == EnvironmentVariableTarget.Process)
- {
- return GetEnvironmentVariableCore(variable);
- }
- else
- {
- RegistryKey baseKey;
- string keyName;
-
- if (target == EnvironmentVariableTarget.Machine)
- {
- baseKey = Registry.LocalMachine;
- keyName = @"System\CurrentControlSet\Control\Session Manager\Environment";
- }
- else
- {
- Debug.Assert(target == EnvironmentVariableTarget.User);
- baseKey = Registry.CurrentUser;
- keyName = "Environment";
- }
-
- using (RegistryKey environmentKey = baseKey.OpenSubKey(keyName, writable: false))
- {
- return environmentKey?.GetValue(variable) as string;
- }
- }
- }
-
- private static IDictionary GetEnvironmentVariablesCore()
- {
- // Format for GetEnvironmentStrings is:
- // (=HiddenVar=value\0 | Variable=value\0)* \0
- // See the description of Environment Blocks in MSDN's
- // CreateProcess page (null-terminated array of null-terminated strings).
- // Note the =HiddenVar's aren't always at the beginning.
-
- // Copy strings out, parsing into pairs and inserting into the table.
- // The first few environment variable entries start with an '='.
- // The current working directory of every drive (except for those drives
- // you haven't cd'ed into in your DOS window) are stored in the
- // environment block (as =C:=pwd) and the program's exit code is
- // as well (=ExitCode=00000000).
-
- var results = new LowLevelDictionary();
- char[] block = GetEnvironmentCharArray();
- for (int i = 0; i < block.Length; i++)
- {
- int startKey = i;
-
- // Skip to key. On some old OS, the environment block can be corrupted.
- // Some will not have '=', so we need to check for '\0'.
- while (block[i] != '=' && block[i] != '\0') i++;
- if (block[i] == '\0') continue;
-
- // Skip over environment variables starting with '='
- if (i - startKey == 0)
- {
- while (block[i] != 0) i++;
- continue;
- }
-
- string key = new string(block, startKey, i - startKey);
- i++; // skip over '='
-
- int startValue = i;
- while (block[i] != 0) i++; // Read to end of this entry
- string value = new string(block, startValue, i - startValue); // skip over 0 handled by for loop's i++
-
- results[key] = value;
- }
- return results;
- }
-
- private static IDictionary GetEnvironmentVariablesCore(EnvironmentVariableTarget target)
- {
- if (target == EnvironmentVariableTarget.Process)
- {
- return GetEnvironmentVariablesCore();
- }
- else
- {
- RegistryKey baseKey;
- string keyName;
- if (target == EnvironmentVariableTarget.Machine)
- {
- baseKey = Registry.LocalMachine;
- keyName = @"System\CurrentControlSet\Control\Session Manager\Environment";
- }
- else
- {
- Debug.Assert(target == EnvironmentVariableTarget.User);
- baseKey = Registry.CurrentUser;
- keyName = @"Environment";
- }
-
- using (RegistryKey environmentKey = baseKey.OpenSubKey(keyName, writable: false))
- {
- var table = new LowLevelDictionary();
- if (environmentKey != null)
- {
- foreach (string name in environmentKey.GetValueNames())
- {
- table.Add(name, environmentKey.GetValue(name, "").ToString());
- }
- }
- return table;
- }
- }
- }
-
- private static unsafe char[] GetEnvironmentCharArray()
- {
- // Format for GetEnvironmentStrings is:
- // [=HiddenVar=value\0]* [Variable=value\0]* \0
- // See the description of Environment Blocks in MSDN's
- // CreateProcess page (null-terminated array of null-terminated strings).
- char* pStrings = Interop.Kernel32.GetEnvironmentStringsW();
- if (pStrings == null)
- {
- throw new OutOfMemoryException();
- }
- try
- {
- // Search for terminating \0\0 (two unicode \0's).
- char* p = pStrings;
- while (!(*p == '\0' && *(p + 1) == '\0')) p++;
-
- var block = new char[(int)(p - pStrings + 1)];
- Marshal.Copy((IntPtr)pStrings, block, 0, block.Length);
- return block;
- }
- finally
- {
- Interop.Kernel32.FreeEnvironmentStringsW(pStrings); // ignore any cleanup error
- }
- }
-
private static string GetFolderPathCore(SpecialFolder folder, SpecialFolderOption option)
{
// We're using SHGetKnownFolderPath instead of SHGetFolderPath as SHGetFolderPath is
@@ -478,82 +319,12 @@ public static int ProcessorCount
return 0;
});
- private static void SetEnvironmentVariableCore(string variable, string value)
- {
- if (!Interop.Kernel32.SetEnvironmentVariableW(variable, value))
- {
- int errorCode = Marshal.GetLastWin32Error();
- switch (errorCode)
- {
- case Interop.Errors.ERROR_ENVVAR_NOT_FOUND: // Allow user to try to clear a environment variable
- return;
- case Interop.Errors.ERROR_FILENAME_EXCED_RANGE: // Fix inaccurate error code from Win32
- throw new ArgumentException(SR.Argument_LongEnvVarValue, nameof(value));
- default:
- throw new ArgumentException(Interop.Kernel32.GetMessage(errorCode));
- }
- }
- }
-
- private static void SetEnvironmentVariableCore(string variable, string value, EnvironmentVariableTarget target)
- {
- if (target == EnvironmentVariableTarget.Process)
- {
- SetEnvironmentVariableCore(variable, value);
- }
- else
- {
- RegistryKey baseKey;
- string keyName;
-
- if (target == EnvironmentVariableTarget.Machine)
- {
- baseKey = Registry.LocalMachine;
- keyName = @"System\CurrentControlSet\Control\Session Manager\Environment";
- }
- else
- {
- Debug.Assert(target == EnvironmentVariableTarget.User);
-
- // User-wide environment variables stored in the registry are limited to 255 chars for the environment variable name.
- const int MaxUserEnvVariableLength = 255;
- if (variable.Length >= MaxUserEnvVariableLength)
- {
- throw new ArgumentException(SR.Argument_LongEnvVarValue, nameof(variable));
- }
-
- baseKey = Registry.CurrentUser;
- keyName = "Environment";
- }
-
- using (RegistryKey environmentKey = baseKey.OpenSubKey(keyName, writable: true))
- {
- if (environmentKey != null)
- {
- if (value == null)
- {
- environmentKey.DeleteValue(variable, throwOnMissingValue: false);
- }
- else
- {
- environmentKey.SetValue(variable, value);
- }
- }
- }
- }
-
- //// Desktop sends a WM_SETTINGCHANGE message to all windows. Not available on all platforms.
- //Interop.Kernel32.SendMessageTimeout(
- // new IntPtr(Interop.Kernel32.HWND_BROADCAST), Interop.Kernel32.WM_SETTINGCHANGE,
- // IntPtr.Zero, "Environment", 0, 1000, IntPtr.Zero);
- }
-
public static string SystemDirectory
{
get
{
- StringBuilder sb = StringBuilderCache.Acquire(Path.MaxPath);
- if (Interop.Kernel32.GetSystemDirectoryW(sb, Path.MaxPath) == 0)
+ StringBuilder sb = StringBuilderCache.Acquire(PathInternal.MaxShortPath);
+ if (Interop.Kernel32.GetSystemDirectoryW(sb, PathInternal.MaxShortPath) == 0)
{
StringBuilderCache.Release(sb);
throw Win32Marshal.GetExceptionForLastWin32Error();
diff --git a/src/System.Runtime.Extensions/src/System/Environment.cs b/src/System.Runtime.Extensions/src/System/Environment.cs
index 97bea9c5f847..2ee6efc7da9e 100644
--- a/src/System.Runtime.Extensions/src/System/Environment.cs
+++ b/src/System.Runtime.Extensions/src/System/Environment.cs
@@ -3,8 +3,6 @@
// See the LICENSE file in the project root for more information.
using Internal.Runtime.Augments;
-using System;
-using System.Collections;
using System.IO;
using System.Reflection;
using System.Text;
@@ -93,42 +91,6 @@ public static string ExpandEnvironmentVariables(string name)
public static string[] GetCommandLineArgs() => EnvironmentAugments.GetCommandLineArgs();
- public static string GetEnvironmentVariable(string variable)
- {
- if (variable == null)
- {
- throw new ArgumentNullException(nameof(variable));
- }
-
- // separated from the EnvironmentVariableTarget overload to help with tree shaking in common case
- return GetEnvironmentVariableCore(variable);
- }
-
- public static string GetEnvironmentVariable(string variable, EnvironmentVariableTarget target)
- {
- if (variable == null)
- {
- throw new ArgumentNullException(nameof(variable));
- }
-
- ValidateTarget(target);
-
- return GetEnvironmentVariableCore(variable, target);
- }
-
- public static IDictionary GetEnvironmentVariables()
- {
- // separated from the EnvironmentVariableTarget overload to help with tree shaking in common case
- return GetEnvironmentVariablesCore();
- }
-
- public static IDictionary GetEnvironmentVariables(EnvironmentVariableTarget target)
- {
- ValidateTarget(target);
-
- return GetEnvironmentVariablesCore(target);
- }
-
public static string GetFolderPath(SpecialFolder folder) => GetFolderPath(folder, SpecialFolderOption.None);
public static string GetFolderPath(SpecialFolder folder, SpecialFolderOption option)
@@ -151,58 +113,6 @@ public static string GetFolderPath(SpecialFolder folder, SpecialFolderOption opt
public static bool Is64BitProcess => IntPtr.Size == 8;
public static bool Is64BitOperatingSystem => Is64BitProcess || Is64BitOperatingSystemWhen32BitProcess;
-
- public static void SetEnvironmentVariable(string variable, string value)
- {
- ValidateVariableAndValue(variable, ref value);
-
- // separated from the EnvironmentVariableTarget overload to help with tree shaking in common case
- SetEnvironmentVariableCore(variable, value);
- }
-
- public static void SetEnvironmentVariable(string variable, string value, EnvironmentVariableTarget target)
- {
- ValidateVariableAndValue(variable, ref value);
- ValidateTarget(target);
-
- SetEnvironmentVariableCore(variable, value, target);
- }
-
- private static void ValidateVariableAndValue(string variable, ref string value)
- {
- const int MaxEnvVariableValueLength = 32767;
-
- if (variable == null)
- {
- throw new ArgumentNullException(nameof(variable));
- }
- if (variable.Length == 0)
- {
- throw new ArgumentException(SR.Argument_StringZeroLength, nameof(variable));
- }
- if (variable[0] == '\0')
- {
- throw new ArgumentException(SR.Argument_StringFirstCharIsZero, nameof(variable));
- }
- if (variable.Length >= MaxEnvVariableValueLength)
- {
- throw new ArgumentException(SR.Argument_LongEnvVarValue, nameof(variable));
- }
- if (variable.IndexOf('=') != -1)
- {
- throw new ArgumentException(SR.Argument_IllegalEnvVarName, nameof(variable));
- }
-
- if (string.IsNullOrEmpty(value) || value[0] == '\0')
- {
- // Explicitly null out value if it's empty
- value = null;
- }
- else if (value.Length >= MaxEnvVariableValueLength)
- {
- throw new ArgumentException(SR.Argument_LongEnvVarValue, nameof(value));
- }
- }
public static OperatingSystem OSVersion => s_osVersion.Value;
@@ -244,15 +154,5 @@ public static long WorkingSet
return 0;
}
}
-
- private static void ValidateTarget(EnvironmentVariableTarget target)
- {
- if (target != EnvironmentVariableTarget.Process &&
- target != EnvironmentVariableTarget.Machine &&
- target != EnvironmentVariableTarget.User)
- {
- throw new ArgumentOutOfRangeException(nameof(target), target, SR.Format(SR.Arg_EnumIllegalVal, target));
- }
- }
}
}