Improve Dictionary TryGetValue size/perfomance (dotnet/coreclr#27195)
[mono-project.git] / netcore / System.Private.CoreLib / shared / System / Environment.Windows.cs
blob17a49080d661a3c87aaf95492546d10b56f60947
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.
5 using System.IO;
6 using System.Runtime.InteropServices;
7 using System.Text;
9 namespace System
11 public static partial class Environment
13 private static string CurrentDirectoryCore
15 get
17 var builder = new ValueStringBuilder(stackalloc char[Interop.Kernel32.MAX_PATH]);
19 uint length;
20 while ((length = Interop.Kernel32.GetCurrentDirectory((uint)builder.Capacity, ref builder.GetPinnableReference())) > builder.Capacity)
22 builder.EnsureCapacity((int)length);
25 if (length == 0)
26 throw Win32Marshal.GetExceptionForLastWin32Error();
28 builder.Length = (int)length;
30 // If we have a tilde in the path, make an attempt to expand 8.3 filenames
31 if (builder.AsSpan().Contains('~'))
33 string result = PathHelper.TryExpandShortFileName(ref builder, null);
34 builder.Dispose();
35 return result;
38 return builder.ToString();
40 set
42 if (!Interop.Kernel32.SetCurrentDirectory(value))
44 int errorCode = Marshal.GetLastWin32Error();
45 throw Win32Marshal.GetExceptionForWin32Error(
46 errorCode == Interop.Errors.ERROR_FILE_NOT_FOUND ? Interop.Errors.ERROR_PATH_NOT_FOUND : errorCode,
47 value);
52 public static string[] GetLogicalDrives() => DriveInfoInternal.GetLogicalDrives();
54 internal const string NewLineConst = "\r\n";
56 public static int SystemPageSize
58 get
60 Interop.Kernel32.GetSystemInfo(out Interop.Kernel32.SYSTEM_INFO info);
61 return info.dwPageSize;
65 private static string ExpandEnvironmentVariablesCore(string name)
67 var builder = new ValueStringBuilder(stackalloc char[128]);
69 uint length;
70 while ((length = Interop.Kernel32.ExpandEnvironmentStrings(name, ref builder.GetPinnableReference(), (uint)builder.Capacity)) > builder.Capacity)
72 builder.EnsureCapacity((int)length);
75 if (length == 0)
76 Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
78 // length includes the null terminator
79 builder.Length = (int)length - 1;
80 return builder.ToString();
83 private static bool Is64BitOperatingSystemWhen32BitProcess =>
84 Interop.Kernel32.IsWow64Process(Interop.Kernel32.GetCurrentProcess(), out bool isWow64) && isWow64;
86 public static string MachineName =>
87 Interop.Kernel32.GetComputerName() ??
88 throw new InvalidOperationException(SR.InvalidOperation_ComputerName);
90 private static unsafe OperatingSystem GetOSVersion()
92 var version = new Interop.Kernel32.OSVERSIONINFOEX { dwOSVersionInfoSize = sizeof(Interop.Kernel32.OSVERSIONINFOEX) };
93 if (!Interop.Kernel32.GetVersionExW(ref version))
95 throw new InvalidOperationException(SR.InvalidOperation_GetVersion);
98 return new OperatingSystem(
99 PlatformID.Win32NT,
100 new Version(version.dwMajorVersion, version.dwMinorVersion, version.dwBuildNumber, (version.wServicePackMajor << 16) | version.wServicePackMinor),
101 Marshal.PtrToStringUni((IntPtr)version.szCSDVersion));
104 public static string SystemDirectory
108 // Normally this will be C:\Windows\System32
109 var builder = new ValueStringBuilder(stackalloc char[32]);
111 uint length;
112 while ((length = Interop.Kernel32.GetSystemDirectoryW(ref builder.GetPinnableReference(), (uint)builder.Capacity)) > builder.Capacity)
114 builder.EnsureCapacity((int)length);
117 if (length == 0)
118 throw Win32Marshal.GetExceptionForLastWin32Error();
120 builder.Length = (int)length;
121 return builder.ToString();
125 public static unsafe long WorkingSet
129 Interop.Kernel32.PROCESS_MEMORY_COUNTERS memoryCounters = default;
130 memoryCounters.cb = (uint)(sizeof(Interop.Kernel32.PROCESS_MEMORY_COUNTERS));
132 if (!Interop.Kernel32.GetProcessMemoryInfo(Interop.Kernel32.GetCurrentProcess(), ref memoryCounters, memoryCounters.cb))
134 return 0;
136 return (long)memoryCounters.WorkingSetSize;