Environment.Windows.cs 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  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.IO;
  5. using System.Runtime.InteropServices;
  6. using System.Text;
  7. namespace System
  8. {
  9. public static partial class Environment
  10. {
  11. private static string CurrentDirectoryCore
  12. {
  13. get
  14. {
  15. var builder = new ValueStringBuilder(stackalloc char[Interop.Kernel32.MAX_PATH]);
  16. uint length;
  17. while ((length = Interop.Kernel32.GetCurrentDirectory((uint)builder.Capacity, ref builder.GetPinnableReference())) > builder.Capacity)
  18. {
  19. builder.EnsureCapacity((int)length);
  20. }
  21. if (length == 0)
  22. throw Win32Marshal.GetExceptionForLastWin32Error();
  23. builder.Length = (int)length;
  24. // If we have a tilde in the path, make an attempt to expand 8.3 filenames
  25. if (builder.AsSpan().Contains('~'))
  26. {
  27. string result = PathHelper.TryExpandShortFileName(ref builder, null);
  28. builder.Dispose();
  29. return result;
  30. }
  31. return builder.ToString();
  32. }
  33. set
  34. {
  35. if (!Interop.Kernel32.SetCurrentDirectory(value))
  36. {
  37. int errorCode = Marshal.GetLastWin32Error();
  38. throw Win32Marshal.GetExceptionForWin32Error(
  39. errorCode == Interop.Errors.ERROR_FILE_NOT_FOUND ? Interop.Errors.ERROR_PATH_NOT_FOUND : errorCode,
  40. value);
  41. }
  42. }
  43. }
  44. public static string[] GetLogicalDrives() => DriveInfoInternal.GetLogicalDrives();
  45. internal const string NewLineConst = "\r\n";
  46. public static int SystemPageSize
  47. {
  48. get
  49. {
  50. Interop.Kernel32.GetSystemInfo(out Interop.Kernel32.SYSTEM_INFO info);
  51. return info.dwPageSize;
  52. }
  53. }
  54. private static string ExpandEnvironmentVariablesCore(string name)
  55. {
  56. var builder = new ValueStringBuilder(stackalloc char[128]);
  57. uint length;
  58. while ((length = Interop.Kernel32.ExpandEnvironmentStrings(name, ref builder.GetPinnableReference(), (uint)builder.Capacity)) > builder.Capacity)
  59. {
  60. builder.EnsureCapacity((int)length);
  61. }
  62. if (length == 0)
  63. Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
  64. // length includes the null terminator
  65. builder.Length = (int)length - 1;
  66. return builder.ToString();
  67. }
  68. private static bool Is64BitOperatingSystemWhen32BitProcess =>
  69. Interop.Kernel32.IsWow64Process(Interop.Kernel32.GetCurrentProcess(), out bool isWow64) && isWow64;
  70. public static string MachineName =>
  71. Interop.Kernel32.GetComputerName() ??
  72. throw new InvalidOperationException(SR.InvalidOperation_ComputerName);
  73. private static unsafe OperatingSystem GetOSVersion()
  74. {
  75. var version = new Interop.Kernel32.OSVERSIONINFOEX { dwOSVersionInfoSize = sizeof(Interop.Kernel32.OSVERSIONINFOEX) };
  76. if (!Interop.Kernel32.GetVersionExW(ref version))
  77. {
  78. throw new InvalidOperationException(SR.InvalidOperation_GetVersion);
  79. }
  80. return new OperatingSystem(
  81. PlatformID.Win32NT,
  82. new Version(version.dwMajorVersion, version.dwMinorVersion, version.dwBuildNumber, (version.wServicePackMajor << 16) | version.wServicePackMinor),
  83. Marshal.PtrToStringUni((IntPtr)version.szCSDVersion));
  84. }
  85. public static string SystemDirectory
  86. {
  87. get
  88. {
  89. // Normally this will be C:\Windows\System32
  90. var builder = new ValueStringBuilder(stackalloc char[32]);
  91. uint length;
  92. while ((length = Interop.Kernel32.GetSystemDirectoryW(ref builder.GetPinnableReference(), (uint)builder.Capacity)) > builder.Capacity)
  93. {
  94. builder.EnsureCapacity((int)length);
  95. }
  96. if (length == 0)
  97. throw Win32Marshal.GetExceptionForLastWin32Error();
  98. builder.Length = (int)length;
  99. return builder.ToString();
  100. }
  101. }
  102. public static unsafe long WorkingSet
  103. {
  104. get
  105. {
  106. Interop.Kernel32.PROCESS_MEMORY_COUNTERS memoryCounters = default;
  107. memoryCounters.cb = (uint)(sizeof(Interop.Kernel32.PROCESS_MEMORY_COUNTERS));
  108. if (!Interop.Kernel32.GetProcessMemoryInfo(Interop.Kernel32.GetCurrentProcess(), ref memoryCounters, memoryCounters.cb))
  109. {
  110. return 0;
  111. }
  112. return (long)memoryCounters.WorkingSetSize;
  113. }
  114. }
  115. }
  116. }