Как найти точный объем физической памяти в Windows x86-32bit с помощью Perl или любого другого языка? - PullRequest
2 голосов
/ 08 января 2009

Мне нужно знать, сколько физической памяти имеет Windows-машина, используя Perl.

Я пытался использовать Win32 :: SystemInfo . Однако этот модуль заявляет следующее предостережение:

На компьютерах Intel x86 с объемом памяти более 2 ГБ и менее 4 ГБ функция MemoryStatus всегда возвращает 2 ГБ для TotalPhys. Точно так же, если общий объем доступной памяти составляет от 2 до 4 ГБ, значение «Доступные» будет округлено до 2 ГБ.

Итак, на машине с 2-4 ГБ физической памяти я получаю ложный ответ.

Есть ли способ получить правильный объем физической памяти? Возможно, другой модуль? Или напрямую используя Win32 :: API ?

Редактировать: Судя по комментариям, приведенным здесь, похоже, что ограничение в Win32 API, а не только в Win32 :: SystemInfo . Однако ОС точно знает , сколько доступно физического плунжера, поэтому должен быть способ извлечь эту информацию. Если не на Perl, то, возможно, на другом языке?

Ответы [ 3 ]

2 голосов
/ 11 января 2009

Как указано в комментариях, это проблема GlobalMemoryStatus , поскольку она может возвращать ответы размером до 2 ГБ. И GlobalMemoryStatusEX , который решает эту проблему ограничения 2 ГБ, но работает только на 64-битных системах (насколько я могу судить).

В конце я использую следующий код Perl, который использует Win32 :: OLE и класс WMI Win32_PhysicalMemory , который возвращает правильный объем физической памяти даже в 32-битных системах:

use strict;
use warnings;
use English;
use Win32::OLE qw( EVENTS HRESULT in );
use Readonly;

sub get_physical_memory {
    my $machine                         = shift || '.'; # Default to local machine
    my Readonly $WMI_MEMORY_CLASS_NAME  = 'Win32_PhysicalMemory';
    my Readonly $MEGABYTE               = 1024*1024;

    my $WMI = 
        Win32::OLE->GetObject( "winmgmts:{impersonationLevel=impersonate,(security)}//$machine/" ) || die "Could not get Win32 object: $OS_ERROR";
    my $total_capacity                  = 0;

    foreach my $object ( in( $WMI->InstancesOf( $WMI_MEMORY_CLASS_NAME ) ) ) {
        $total_capacity += $object->{Capacity};
    }

    my $total_capacity_in_mb            = $total_capacity / $MEGABYTE;
    print "Total Memory : $total_capacity_in_mb \n";
    return $total_capacity_in_mb;
}
1 голос
/ 10 января 2009

Эта информация может быть получена из WMI или с использованием SNMP, если вы решите включить SNMP на устройстве, на котором он будет работать. Для WMI у меня нет примера Perl, но пример VBScript см. Ниже.

Ссылка: http://www.microsoft.com/technet/scriptcenter/guide/sas_wmi_dieu.mspx

strComputer = "."

Set objSWbemServices = GetObject("winmgmts:\\" & strComputer)
Set colSWbemObjectSet = _
 objSWbemServices.InstancesOf("Win32_LogicalMemoryConfiguration")

For Each objSWbemObject In colSWbemObjectSet
 Wscript.Echo "Total Physical Memory (kb): " & _
 objSWbemObject.TotalPhysicalMemory
Next

Проверено на моей системе XP, и она получает желаемые результаты (только 1,5 ГБ ОЗУ здесь, извините). Я вполне уверен, что есть интерфейсы WMI для Perl, если вы хотите придерживаться Perl. Если опция SNMP является опцией, общий объем физической памяти также можно получить из SNMP, используя одну из библиотек Perl SNMP.

РЕДАКТИРОВАТЬ : Только что заметил @Mr. Комментарий Маскрата относительно Microsoft KB http://support.microsoft.com/kb/274558 - очевидно, что поведение, которое вы видите с Perl, является ограничением вызова Win32 API, поэтому вы можете получить те же результаты с WMI. К сожалению, у меня нет 2-4 ГБ ОЗУ, чтобы проверить это.

1 голос
/ 09 января 2009

Я могу только предположить, что предостережения, сопровождающие результаты Win32::SystemInfo, также являются предостережениями, которые посещают необработанные вызовы Win32 API, поскольку сам Perl, безусловно, не имеет проблем с обработкой таких больших чисел. В этом случае возможность получения точной информации выглядит немного мрачно.

Я также мимоходом слышал, что текущие 32-разрядные версии Windows могут использовать только около 3,2 ГБ ОЗУ на компьютере, на котором установлено> = 4 ГБ, что может показаться слухом, но это противоречит ограничению в Сам API.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...