So my application requires knowing total RAM available. At least 4 different ways exist, as far as I'm concerned:
- Query Windows Menagement Instrumentation (WMI)
- Get it from Microsoft.VisualBasic.Devices.ComputerInfo.TotalPhysicalMemory
- Query WinAPI
- Use P-Invoke
I like the first two, hovewer they give slightly different results on my machine (2 sticks of 2GB each, Windows 8.1 64 bit).
The code I use to get it from VisualBasic dll:
class Program
{
private static readonly Lazy<ComputerInfo> ComputerInfo = new Lazy<ComputerInfo>();
public static ulong TotalRam => ComputerInfo.Value.TotalPhysicalMemory;
static void Main(string[] args)
{
Console.WriteLine("Total RAM from ComputerInfo: {0} bytes", TotalRam);
// Result: Total RAM from ComputerInfo: 4292902912 bytes
}
}
The code I use to get it from Windows Management:
class Program
{
public static IEnumerable<object> GetResults(string win32ClassName, string property)
{
return (from x in new ManagementObjectSearcher("SELECT * FROM " + win32ClassName).Get().OfType<ManagementObject>()
select x.GetPropertyValue(property));
}
public static ulong? TotalInstalledBytes
{
get
{
var values = GetResults("Win32_PhysicalMemory", "Capacity");
ulong? sum = null;
foreach (var item in values)
{
var casted = item as ulong?;
if (casted.HasValue)
{
if (sum == null) sum = 0;
sum += casted.Value;
}
}
return sum;
}
}
static void Main(string[] args)
{
Console.WriteLine("Total RAM from WMI: {0} bytes", TotalInstalledBytes);
// Result: Total RAM from WMI: 4294967296 bytes
}
}
The difference is slightly less than 2 MB, 2064384 bytes or 2016 kB exactly. My question is: why is that so?
My guesses would be either:
- VisualBasic ComputerInfo returns memory seen from the OS perspective, while WMI uses the manufacturer 'hardcoded' values
- VisualBasic ComputerInfo returns memory that is really there (it appears, that the memory sticks commercially availabe rarely have the exact amount of bytes), while WMI uses the manufacturer 'hardcoded' values
Thanks for responses.