如何获得笔记本电脑或台式机支持的最大内存大小?

时间:2013-04-22 20:32:27

标签: delphi winapi wmi

我正在使用Delphi构建软件以获取一些硬件信息,我需要使用delphi获得笔记本电脑或台式机支持的最大内存(RAM)大小,到目前为止我一直在寻找WinApi或WMI功能获取该信息,但我没有找到任何与此相关的信息。如何获得笔记本电脑或台式机支持的最大内存大小?

2 个答案:

答案 0 :(得分:6)

您可以使用SMBIOS获取该信息,请尝试阅读有关Physical Memory Array (Type 16)表的文档。您可以parse and extract the SMBIOS tables manually或使用TSMBIOS等库。

尝试使用TSMBIOS库的此示例。

{$APPTYPE CONSOLE}

uses
  Classes,
  SysUtils,
  uSMBIOS in '..\..\Common\uSMBIOS.pas';

function  GetMaxMemoryCapacity : UInt32;
Var
  SMBios : TSMBios;
  LPhysicalMemArr  : TPhysicalMemoryArrayInformation;
begin
  result:=0;
  SMBios:=TSMBios.Create;
  try
      if SMBios.HasPhysicalMemoryArrayInfo then
      for LPhysicalMemArr in SMBios.PhysicalMemoryArrayInfo do
      begin
        if LPhysicalMemArr.RAWPhysicalMemoryArrayInformation.MaximumCapacity<>$80000000 then
          result:=result+(LPhysicalMemArr.RAWPhysicalMemoryArrayInformation.MaximumCapacity*LPhysicalMemArr.RAWPhysicalMemoryArrayInformation.NumberofMemoryDevices)
        else
          result:=result+((LPhysicalMemArr.RAWPhysicalMemoryArrayInformation.ExtendedMaximumCapacity div 1024)*LPhysicalMemArr.RAWPhysicalMemoryArrayInformation.NumberofMemoryDevices);
      end
      else raise Exception.Create('No Physical Memory Array Info was found');
  finally
   SMBios.Free;
  end;
end;


begin
 try
    Writeln(Format('Max Memory Capacity installable %d kb',[GetMaxMemoryCapacity]));
 except
    on E:Exception do
        Writeln(E.Classname, ':', E.Message);
 end;
 Writeln('Press Enter to exit');
 Readln;
end.

答案 1 :(得分:5)

您可以使用Win32_PhysicalMemoryArray WMI类和MaxCapacity属性。

  

MaxCapacity:可安装的最大内存大小(以字节为单位)   特定的内存阵列。如果大小未知,则给出属性   值为0(零)。

此属性可以返回以字节或千字节为单位的大小,因此您必须先检查属性的Units限定符才能使用它。

试试这个样本

{$APPTYPE CONSOLE}


uses
  SysUtils,
  ActiveX,
  ComObj,
  Variants;

function  GetQualifierValue(Const NameSpace, ClassName, PropName, QualifName : string) :string;
const
  wbemFlagUseAmendedQualifiers = $00020000;
Var
  Properties        : OleVariant;
  Qualifiers        : OleVariant;
  rgvarProp         : OleVariant;
  rgvarQualif       : OleVariant;
  objSWbemLocator   : OleVariant;
  objSWbemObjectSet : OleVariant;
  objWMIService     : OleVariant;
  EnumProps         : IEnumVariant;
  EnumQualif        : IEnumVariant;
  pceltFetched      : Cardinal;
  Lindex            : Integer;
begin
  Result:='';
  objSWbemLocator  := CreateOleObject('WbemScripting.SWbemLocator');
  objWMIService    := objSWbemLocator.ConnectServer('localhost', NameSpace, '', '');
  objSWbemObjectSet:= objWMIService.Get(ClassName, wbemFlagUseAmendedQualifiers);
  Properties := objSWbemObjectSet.Properties_;
  EnumProps         := IUnknown(Properties._NewEnum) as IEnumVariant;
  while EnumProps.Next(1, rgvarProp, pceltFetched) = 0 do
  begin
    if SameText(rgvarProp.Name, PropName) then
    begin
      Qualifiers      := rgvarProp.Qualifiers_;
      EnumQualif     := IUnknown(Qualifiers._NewEnum) as IEnumVariant;
      while EnumQualif.Next(1, rgvarQualif, pceltFetched) = 0 do
      begin
        if SameText(QualifName, rgvarQualif.Name) then
        begin
           if not VarIsNull(rgvarQualif.Value)  then
            Result:=rgvarQualif.Value;
           Break;
        end;
        rgvarQualif:=Unassigned;
      end;
      Break;
    end;
    rgvarProp:=Unassigned;
  end;
end;


function  GetMaxMemoryCapacity : UInt32;
var
  FSWbemLocator : OLEVariant;
  FWMIService   : OLEVariant;
  FWbemObjectSet: OLEVariant;
  FWbemObject   : OLEVariant;
  oEnum         : IEnumvariant;
  iValue        : LongWord;
  UnitsName     : string;
begin;
  Result:=0;
  FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
  FWMIService   := FSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', '');
  UnitsName     := GetQualifierValue('root\CIMV2','Win32_PhysicalMemoryArray','MaxCapacity','Units');
  FWbemObjectSet:= FWMIService.ExecQuery('SELECT MaxCapacity,MemoryDevices FROM Win32_PhysicalMemoryArray','WQL',$00000020);
  oEnum         := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
  while oEnum.Next(1, FWbemObject, iValue) = 0 do
  begin
    if SameText('kilobytes', UnitsName) then
     Result:=Result+(UInt32(FWbemObject.MaxCapacity)*UInt32(FWbemObject.MemoryDevices))
    else
     Result:=Result+((UInt32(FWbemObject.MaxCapacity) div 1024)*UInt32(FWbemObject.MemoryDevices));
    FWbemObject:=Unassigned;
  end;
end;