2023-03-04 14:43:08 +01:00
|
|
|
using Ryujinx.Common.Logging;
|
2020-07-30 21:02:06 +02:00
|
|
|
using System;
|
2020-05-04 04:15:27 +02:00
|
|
|
using System.Management;
|
2020-07-30 21:02:06 +02:00
|
|
|
using System.Runtime.InteropServices;
|
2020-11-27 18:57:20 +01:00
|
|
|
using System.Runtime.Versioning;
|
2020-05-04 04:15:27 +02:00
|
|
|
|
|
|
|
namespace Ryujinx.Common.SystemInfo
|
|
|
|
{
|
2020-11-27 18:57:20 +01:00
|
|
|
[SupportedOSPlatform("windows")]
|
2022-12-15 18:07:31 +01:00
|
|
|
partial class WindowsSystemInfo : SystemInfo
|
2020-05-04 04:15:27 +02:00
|
|
|
{
|
2021-03-01 05:22:00 +01:00
|
|
|
internal WindowsSystemInfo()
|
|
|
|
{
|
|
|
|
CpuName = $"{GetCpuidCpuName() ?? GetCpuNameWMI()} ; {LogicalCoreCount} logical"; // WMI is very slow
|
|
|
|
(RamTotal, RamAvailable) = GetMemoryStats();
|
|
|
|
}
|
2020-05-04 04:15:27 +02:00
|
|
|
|
2021-03-01 05:22:00 +01:00
|
|
|
private static (ulong Total, ulong Available) GetMemoryStats()
|
2020-05-04 04:15:27 +02:00
|
|
|
{
|
2021-03-01 05:22:00 +01:00
|
|
|
MemoryStatusEx memStatus = new MemoryStatusEx();
|
2022-12-15 18:07:31 +01:00
|
|
|
if (GlobalMemoryStatusEx(ref memStatus))
|
2021-03-01 05:22:00 +01:00
|
|
|
{
|
|
|
|
return (memStatus.TotalPhys, memStatus.AvailPhys); // Bytes
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Logger.Error?.Print(LogClass.Application, $"GlobalMemoryStatusEx failed. Error {Marshal.GetLastWin32Error():X}");
|
|
|
|
}
|
2020-07-30 21:02:06 +02:00
|
|
|
|
2021-03-01 05:22:00 +01:00
|
|
|
return (0, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
private static string GetCpuNameWMI()
|
|
|
|
{
|
|
|
|
ManagementObjectCollection cpuObjs = GetWMIObjects("root\\CIMV2", "SELECT * FROM Win32_Processor");
|
|
|
|
|
|
|
|
if (cpuObjs != null)
|
2020-07-30 21:02:06 +02:00
|
|
|
{
|
2021-03-01 05:22:00 +01:00
|
|
|
foreach (var cpuObj in cpuObjs)
|
2020-07-30 21:02:06 +02:00
|
|
|
{
|
2021-03-01 05:22:00 +01:00
|
|
|
return cpuObj["Name"].ToString().Trim();
|
2020-07-30 21:02:06 +02:00
|
|
|
}
|
2021-03-01 05:22:00 +01:00
|
|
|
}
|
2020-07-30 21:02:06 +02:00
|
|
|
|
2021-03-01 05:22:00 +01:00
|
|
|
return Environment.GetEnvironmentVariable("PROCESSOR_IDENTIFIER").Trim();
|
|
|
|
}
|
|
|
|
|
2022-12-15 18:07:31 +01:00
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
|
|
private struct MemoryStatusEx
|
2021-03-01 05:22:00 +01:00
|
|
|
{
|
|
|
|
public uint Length;
|
|
|
|
public uint MemoryLoad;
|
|
|
|
public ulong TotalPhys;
|
|
|
|
public ulong AvailPhys;
|
|
|
|
public ulong TotalPageFile;
|
|
|
|
public ulong AvailPageFile;
|
|
|
|
public ulong TotalVirtual;
|
|
|
|
public ulong AvailVirtual;
|
|
|
|
public ulong AvailExtendedVirtual;
|
|
|
|
|
|
|
|
public MemoryStatusEx()
|
|
|
|
{
|
2022-12-12 15:10:05 +01:00
|
|
|
Length = (uint)Marshal.SizeOf<MemoryStatusEx>();
|
2020-07-30 21:02:06 +02:00
|
|
|
}
|
2021-03-01 05:22:00 +01:00
|
|
|
}
|
|
|
|
|
2022-12-15 18:07:31 +01:00
|
|
|
[LibraryImport("kernel32.dll", SetLastError = true)]
|
2021-03-01 05:22:00 +01:00
|
|
|
[return: MarshalAs(UnmanagedType.Bool)]
|
2022-12-15 18:07:31 +01:00
|
|
|
private static partial bool GlobalMemoryStatusEx(ref MemoryStatusEx lpBuffer);
|
2021-03-01 05:22:00 +01:00
|
|
|
|
|
|
|
private static ManagementObjectCollection GetWMIObjects(string scope, string query)
|
|
|
|
{
|
|
|
|
try
|
2020-05-04 04:15:27 +02:00
|
|
|
{
|
2021-03-01 05:22:00 +01:00
|
|
|
return new ManagementObjectSearcher(scope, query).Get();
|
2020-07-30 21:02:06 +02:00
|
|
|
}
|
2021-03-01 05:22:00 +01:00
|
|
|
catch (PlatformNotSupportedException ex)
|
2020-07-30 21:02:06 +02:00
|
|
|
{
|
2021-03-01 05:22:00 +01:00
|
|
|
Logger.Error?.Print(LogClass.Application, $"WMI isn't available : {ex.Message}");
|
2020-05-04 04:15:27 +02:00
|
|
|
}
|
2021-03-01 05:22:00 +01:00
|
|
|
catch (COMException ex)
|
2020-05-04 04:15:27 +02:00
|
|
|
{
|
2021-03-01 05:22:00 +01:00
|
|
|
Logger.Error?.Print(LogClass.Application, $"WMI isn't available : {ex.Message}");
|
2020-05-04 04:15:27 +02:00
|
|
|
}
|
2021-03-01 05:22:00 +01:00
|
|
|
|
|
|
|
return null;
|
2020-05-04 04:15:27 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|