I am trying to determine an amount of physical memory installed in a computer. To acomplish this I am using WMI (through .net 4.0) and it's services. The problem is that no matter what amount of memory remote computer has, value returned is 4GB. This has been tested with three remote computers:
- Virtual machine, 1GB RAM, Windows 2003
- Physical machine, 2GB RAM, Windows XP
- Physical machine, 2GB RAM, Windows 7 64bit
I myself am running physical machine, 4GB RAM, Windows 7 64bit.
Showing the code:
uint phisicalMemorySize = 0;
ConnectionOptions co = new ConnectionOptions();
co.Username = null;
ManagementScope ms = new ManagementScope("\\\\" + computerName, co);
ObjectQuery q = new ObjectQuery("select TotalPhysicalMemory from Win32_ComputerSystem");
ManagementObjectSearcher os = new ManagementObjectSearcher(ms, q);
ManagementObjectCollection moc = os.Get();
foreach (ManagementObject o in moc)
{
phisicalMemorySize += Convert.ToUInt64(o["TotalPhysicalMemory"], CultureInfo.InvariantCulture);
}
I have also tried using select Capacity from Win32_PhysicalMemory
and select TotalVisibleMemorySize from Win32_OperatingSystem
as queries but to no avail. At the end phisicalMemorySize
would allways be 4GB.
TotalPhysicalMemory has a loud disclaimer in the MSDN Library docs:
Total size of physical memory. Be
aware that, under some circumstances,
this property may not return an
accurate value for the physical
memory. For example, it is not
accurate if the BIOS is using some of
the physical memory. For an accurate
value, use the Capacity property in
Win32_PhysicalMemory instead.
Afaik, all modern machines copy their BIOS to memory. I think the Capacity property is how much memory is usable in the machine, not how much is present. Which is 2 gigabytes on any 32-bit operating system, 4 gigabytes for a 32-bit process on a 64-bit operating system. Compare to, say, the List<>.Capacity vs Count property.
I'm getting a decent value for TotalPhys, 3 gigabytes which I know I have on my laptop. Capacity is 2 gigabytes, matches the operating system. WMI does get flaky sometimes, it is hardly perfect.
Use the WMI Code Creator utility to get a second opinion. I think it is a .NET 1.1 program so beware of its results if you run it against a 64-bit operating system. If you use Visual Studio 2010 then watch out for the Platform Target setting in your project. It defaults to x86 so you'll run in 32-bit mode, even on a 64-bit operating system. Project + Properties, Build tab, Platform target setting.
Found the problem. It is with the
ManagementScope ms = new ManagementScope("\\\\" + computerName, co);
line. The correct would be
ManagementScope ms = new ManagementScope("\\\\" + computerName + "\\root\\CIMV2", co);
It looks like it defaulted to the local computer.
Thanks to Hans who pointed me to WMI Code Creator. That tool realy helped a great deal.