/ src / Ryujinx.UI.Common / SystemInfo / WindowsSystemInfo.cs
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  }