WindowsSystemInfo.cs 2.8 KB

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