WindowsSystemInfo.cs 2.9 KB

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