WindowsSystemInfo.cs
1 using Ryujinx.Common.Logging; 2 using System; 3 using System.Management; 4 using System.Runtime.InteropServices; 5 using System.Runtime.Versioning; 6 7 namespace Ryujinx.UI.Common.SystemInfo 8 { 9 [SupportedOSPlatform("windows")] 10 partial class WindowsSystemInfo : SystemInfo 11 { 12 internal WindowsSystemInfo() 13 { 14 CpuName = $"{GetCpuidCpuName() ?? GetCpuNameWMI()} ; {LogicalCoreCount} logical"; // WMI is very slow 15 (RamTotal, RamAvailable) = GetMemoryStats(); 16 } 17 18 private static (ulong Total, ulong Available) GetMemoryStats() 19 { 20 MemoryStatusEx memStatus = new(); 21 if (GlobalMemoryStatusEx(ref memStatus)) 22 { 23 return (memStatus.TotalPhys, memStatus.AvailPhys); // Bytes 24 } 25 26 Logger.Error?.Print(LogClass.Application, $"GlobalMemoryStatusEx failed. Error {Marshal.GetLastWin32Error():X}"); 27 28 return (0, 0); 29 } 30 31 private static string GetCpuNameWMI() 32 { 33 ManagementObjectCollection cpuObjs = GetWMIObjects("root\\CIMV2", "SELECT * FROM Win32_Processor"); 34 35 if (cpuObjs != null) 36 { 37 foreach (var cpuObj in cpuObjs) 38 { 39 return cpuObj["Name"].ToString().Trim(); 40 } 41 } 42 43 return Environment.GetEnvironmentVariable("PROCESSOR_IDENTIFIER").Trim(); 44 } 45 46 [StructLayout(LayoutKind.Sequential)] 47 private struct MemoryStatusEx 48 { 49 public uint Length; 50 public uint MemoryLoad; 51 public ulong TotalPhys; 52 public ulong AvailPhys; 53 public ulong TotalPageFile; 54 public ulong AvailPageFile; 55 public ulong TotalVirtual; 56 public ulong AvailVirtual; 57 public ulong AvailExtendedVirtual; 58 59 public MemoryStatusEx() 60 { 61 Length = (uint)Marshal.SizeOf<MemoryStatusEx>(); 62 } 63 } 64 65 [LibraryImport("kernel32.dll", SetLastError = true)] 66 [return: MarshalAs(UnmanagedType.Bool)] 67 private static partial bool GlobalMemoryStatusEx(ref MemoryStatusEx lpBuffer); 68 69 private static ManagementObjectCollection GetWMIObjects(string scope, string query) 70 { 71 try 72 { 73 return new ManagementObjectSearcher(scope, query).Get(); 74 } 75 catch (PlatformNotSupportedException ex) 76 { 77 Logger.Error?.Print(LogClass.Application, $"WMI isn't available : {ex.Message}"); 78 } 79 catch (COMException ex) 80 { 81 Logger.Error?.Print(LogClass.Application, $"WMI isn't available : {ex.Message}"); 82 } 83 84 return null; 85 } 86 } 87 }