Environment.cs 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the MIT license.
  3. // See the LICENSE file in the project root for more information.
  4. using System.Collections;
  5. using System.Collections.Generic;
  6. using System.Diagnostics;
  7. using System.Reflection;
  8. namespace System
  9. {
  10. public static partial class Environment
  11. {
  12. public static string GetEnvironmentVariable(string variable)
  13. {
  14. if (variable == null)
  15. throw new ArgumentNullException(nameof(variable));
  16. return GetEnvironmentVariableCore(variable);
  17. }
  18. public static string GetEnvironmentVariable(string variable, EnvironmentVariableTarget target)
  19. {
  20. if (target == EnvironmentVariableTarget.Process)
  21. return GetEnvironmentVariable(variable);
  22. if (variable == null)
  23. throw new ArgumentNullException(nameof(variable));
  24. bool fromMachine = ValidateAndConvertRegistryTarget(target);
  25. return GetEnvironmentVariableFromRegistry(variable, fromMachine);
  26. }
  27. public static IDictionary GetEnvironmentVariables(EnvironmentVariableTarget target)
  28. {
  29. if (target == EnvironmentVariableTarget.Process)
  30. return GetEnvironmentVariables();
  31. bool fromMachine = ValidateAndConvertRegistryTarget(target);
  32. return GetEnvironmentVariablesFromRegistry(fromMachine);
  33. }
  34. public static void SetEnvironmentVariable(string variable, string value)
  35. {
  36. ValidateVariableAndValue(variable, ref value);
  37. SetEnvironmentVariableCore(variable, value);
  38. }
  39. public static void SetEnvironmentVariable(string variable, string value, EnvironmentVariableTarget target)
  40. {
  41. if (target == EnvironmentVariableTarget.Process)
  42. {
  43. SetEnvironmentVariable(variable, value);
  44. return;
  45. }
  46. ValidateVariableAndValue(variable, ref value);
  47. bool fromMachine = ValidateAndConvertRegistryTarget(target);
  48. SetEnvironmentVariableFromRegistry(variable, value, fromMachine: fromMachine);
  49. }
  50. public static string CommandLine => PasteArguments.Paste(GetCommandLineArgs(), pasteFirstArgumentUsingArgV0Rules: true);
  51. public static string CurrentDirectory
  52. {
  53. get => CurrentDirectoryCore;
  54. set
  55. {
  56. if (value == null)
  57. throw new ArgumentNullException(nameof(value));
  58. if (value.Length == 0)
  59. throw new ArgumentException(SR.Argument_PathEmpty, nameof(value));
  60. CurrentDirectoryCore = value;
  61. }
  62. }
  63. public static string ExpandEnvironmentVariables(string name)
  64. {
  65. if (name == null)
  66. throw new ArgumentNullException(nameof(name));
  67. if (name.Length == 0)
  68. return name;
  69. return ExpandEnvironmentVariablesCore(name);
  70. }
  71. private static string[] s_commandLineArgs;
  72. internal static void SetCommandLineArgs(string[] cmdLineArgs) // invoked from VM
  73. {
  74. s_commandLineArgs = cmdLineArgs;
  75. }
  76. public static string GetFolderPath(SpecialFolder folder) => GetFolderPath(folder, SpecialFolderOption.None);
  77. public static string GetFolderPath(SpecialFolder folder, SpecialFolderOption option)
  78. {
  79. if (!Enum.IsDefined(typeof(SpecialFolder), folder))
  80. throw new ArgumentOutOfRangeException(nameof(folder), folder, SR.Format(SR.Arg_EnumIllegalVal, folder));
  81. if (option != SpecialFolderOption.None && !Enum.IsDefined(typeof(SpecialFolderOption), option))
  82. throw new ArgumentOutOfRangeException(nameof(option), option, SR.Format(SR.Arg_EnumIllegalVal, option));
  83. return GetFolderPathCore(folder, option);
  84. }
  85. public static bool Is64BitProcess => IntPtr.Size == 8;
  86. public static bool Is64BitOperatingSystem => Is64BitProcess || Is64BitOperatingSystemWhen32BitProcess;
  87. public static OperatingSystem OSVersion => s_osVersion.Value;
  88. public static bool UserInteractive => true;
  89. // Previously this represented the File version of mscorlib.dll. Many other libraries in the framework and outside took dependencies on the first three parts of this version
  90. // remaining constant throughout 4.x. From 4.0 to 4.5.2 this was fine since the file version only incremented the last part. Starting with 4.6 we switched to a file versioning
  91. // scheme that matched the product version. In order to preserve compatibility with existing libraries, this needs to be hard-coded.
  92. public static Version Version => new Version(4, 0, 30319, 42000);
  93. public static long WorkingSet
  94. {
  95. get
  96. {
  97. // Use reflection to access the implementation in System.Diagnostics.Process.dll. While far from ideal,
  98. // we do this to avoid duplicating the Windows, Linux, macOS, and potentially other platform-specific implementations
  99. // present in Process. If it proves important, we could look at separating that functionality out of Process into
  100. // Common files which could also be included here.
  101. Type processType = Type.GetType("System.Diagnostics.Process, System.Diagnostics.Process, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", throwOnError: false);
  102. IDisposable currentProcess = processType?.GetMethod("GetCurrentProcess")?.Invoke(null, BindingFlags.DoNotWrapExceptions, null, null, null) as IDisposable;
  103. if (currentProcess != null)
  104. {
  105. using (currentProcess)
  106. {
  107. object result = processType.GetMethod("get_WorkingSet64")?.Invoke(currentProcess, BindingFlags.DoNotWrapExceptions, null, null, null);
  108. if (result is long) return (long)result;
  109. }
  110. }
  111. // Could not get the current working set.
  112. return 0;
  113. }
  114. }
  115. private static bool ValidateAndConvertRegistryTarget(EnvironmentVariableTarget target)
  116. {
  117. Debug.Assert(target != EnvironmentVariableTarget.Process);
  118. if (target == EnvironmentVariableTarget.Machine)
  119. return true;
  120. if (target == EnvironmentVariableTarget.User)
  121. return false;
  122. throw new ArgumentOutOfRangeException(nameof(target), target, SR.Format(SR.Arg_EnumIllegalVal, target));
  123. }
  124. private static void ValidateVariableAndValue(string variable, ref string value)
  125. {
  126. if (variable == null)
  127. throw new ArgumentNullException(nameof(variable));
  128. if (variable.Length == 0)
  129. throw new ArgumentException(SR.Argument_StringZeroLength, nameof(variable));
  130. if (variable[0] == '\0')
  131. throw new ArgumentException(SR.Argument_StringFirstCharIsZero, nameof(variable));
  132. if (variable.Contains('='))
  133. throw new ArgumentException(SR.Argument_IllegalEnvVarName, nameof(variable));
  134. if (string.IsNullOrEmpty(value) || value[0] == '\0')
  135. {
  136. // Explicitly null out value if it's empty
  137. value = null;
  138. }
  139. }
  140. }
  141. }