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.
6 using System
.Runtime
.InteropServices
;
11 public static partial class Environment
13 private static string CurrentDirectoryCore
17 var builder
= new ValueStringBuilder(stackalloc char[Interop
.Kernel32
.MAX_PATH
]);
20 while ((length
= Interop
.Kernel32
.GetCurrentDirectory((uint)builder
.Capacity
, ref builder
.GetPinnableReference())) > builder
.Capacity
)
22 builder
.EnsureCapacity((int)length
);
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);
38 return builder
.ToString();
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
,
52 public static string[] GetLogicalDrives() => DriveInfoInternal
.GetLogicalDrives();
54 internal const string NewLineConst
= "\r\n";
56 public static int SystemPageSize
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]);
70 while ((length
= Interop
.Kernel32
.ExpandEnvironmentStrings(name
, ref builder
.GetPinnableReference(), (uint)builder
.Capacity
)) > builder
.Capacity
)
72 builder
.EnsureCapacity((int)length
);
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(
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]);
112 while ((length
= Interop
.Kernel32
.GetSystemDirectoryW(ref builder
.GetPinnableReference(), (uint)builder
.Capacity
)) > builder
.Capacity
)
114 builder
.EnsureCapacity((int)length
);
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
))
136 return (long)memoryCounters
.WorkingSetSize
;