2

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

4

2 回答 2

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.
于 2013-04-22T21:12:21.237 回答
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;
于 2013-04-22T21:01:02.457 回答