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

Sal*_*dor 2 delphi wmi winapi

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

RRU*_*RUZ 6

您可以使用SMBIOS获取该信息,尝试阅读有关Physical Memory Array (Type 16)表的文档.您可以手动解析和提取SMBIOS表,也可以使用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.
Run Code Online (Sandbox Code Playgroud)


RRU*_*RUZ 5

您可以使用Win32_PhysicalMemoryArrayWMI类和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;
Run Code Online (Sandbox Code Playgroud)