Проблема с чтением объема памяти на удаленном компьютере

#c# #wmi

#c# #wmi

Вопрос:

Я пытаюсь определить объем физической памяти, установленный на компьютере. Для выполнения этого я использую WMI (через .net 4.0) и его службы. Проблема в том, что независимо от того, какой объем памяти имеется на удаленном компьютере, возвращаемое значение равно 4 ГБ. Это было протестировано на трех удаленных компьютерах:

  • Виртуальная машина, 1 ГБ оперативной памяти, Windows 2003
  • Физическая машина, 2 ГБ оперативной памяти, Windows XP
  • Физическая машина, 2 ГБ оперативной памяти, 64-разрядная Windows 7

Я сам использую физическую машину, 4 ГБ оперативной памяти, 64-битную Windows 7.

Отображение кода:

 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);
}
  

Я также пробовал использовать select Capacity from Win32_PhysicalMemory
и select TotalVisibleMemorySize from Win32_OperatingSystem в виде запросов, но безрезультатно. В конце phisicalMemorySize всегда будет 4 ГБ.

Ответ №1:

TotalPhysicalMemory имеет громкое заявление об отказе от ответственности в документах библиотеки MSDN:

Общий размер физической памяти. Имейте в виду, что при некоторых обстоятельствах это свойство может возвращать неточное значение для физической памяти. Например, неточно, использует ли BIOS часть физической памяти. Для получения точного значения вместо этого используйте свойство Capacity в Win32_PhysicalMemory.

Afaik, все современные машины копируют свои BIOS в память. Я думаю, что свойство Capacity — это то, сколько памяти можно использовать на компьютере, а не то, сколько ее присутствует. Что составляет 2 гигабайта в любой 32-разрядной операционной системе, 4 гигабайта для 32-разрядного процесса в 64-разрядной операционной системе. Сравните, скажем, со свойством List<>.Capacity vs Count.

Я получаю приличное значение для TotalPhys, 3 гигабайта, которые, как я знаю, у меня есть на моем ноутбуке. Объем составляет 2 гигабайта, соответствует операционной системе. WMI иногда становится ненадежным, его вряд ли можно назвать идеальным.

Используйте утилиту WMI Code Creator, чтобы получить второе мнение. Я думаю, что это программа .NET 1.1, поэтому остерегайтесь ее результатов, если вы запустите ее в 64-разрядной операционной системе. Если вы используете Visual Studio 2010, то следите за настройками целевой платформы в вашем проекте. По умолчанию используется x86, поэтому вы будете работать в 32-разрядном режиме даже в 64-разрядной операционной системе. Проект Свойства, вкладка сборка, настройка целевой платформы.

Комментарии:

1. Я уверен, что вы ошибаетесь насчет емкости. Он возвращает емкость каждого накопителя ( щелчок ), конечно, при условии, что внутри WMI ничего не изменилось. Также насколько велик BIOS в оперативной памяти? 100 МБ? Это не должно сильно исказить мои результаты. Какой класс и свойство вы использовали, чтобы получить упомянутые 3 ГБ в вашем ноутбуке?

Ответ №2:

Обнаружена проблема. Это связано с

 ManagementScope ms = new ManagementScope("\\"   computerName, co);
  

строка. Правильным было бы

 ManagementScope ms = new ManagementScope("\\"   computerName   "\root\CIMV2", co);
  

Похоже, что по умолчанию он установлен на локальном компьютере.

Спасибо Гансу, который указал мне на WMI Code Creator. Этот инструмент действительно очень помог.