WindowsSystemInfo.cs 2.8 KB

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