delphicpudelphi-11-alexandria

How to get processor information with Delphi using no third party units?


I need to get the processor name using Delphi. Nothing fancy, i just need to retrieve what Windows System > About shows ; in the example below, i want to retrieve the '13th Gen Intel(R) Core(TM) i9-13000H 2.60ghz' as string.

I saw some examples but all of them use third party unit / components. Any way to get this using just what comes with Delphi 11 ?

enter image description here


Solution

  • You can find this information in the Registry:

    Here is an example function (taken from Dalija's answer):

    function GetCPUName: string;
    var
      Reg: TRegistry;
    begin
      Result := '';
      Reg := TRegistry.Create;
      try
        Reg.RootKey := HKEY_LOCAL_MACHINE;
        if Reg.OpenKeyReadOnly('\Hardware\Description\System\CentralProcessor\0') then
          begin
            Result := Reg.ReadString('ProcessorNameString');
            Reg.CloseKey;
          end;
      finally
        Reg.Free;
      end;
    end;
    

    As mentioned in the comments, there is a method that is OS independent using CPUID :

    program Project1;
    
    {$APPTYPE CONSOLE}
    
    {$R *.res}
    
    uses
      System.SysUtils;
    
    type
      TCPUID = packed record
        rEAX: UInt32; { EAX Register }
        rEBX: UInt32; { EBX Register }
        rEDX: UInt32; { EDX Register }
        rECX: UInt32; { ECX Register }
      end;
    
    function GetCPUID(Leaf, Subleaf: Integer): TCPUID;
    asm
    {$IF Defined(CPUX86)}
      push  ebx
      push  edi
      mov   edi, ecx
      mov   ecx, edx
      cpuid
      mov   [edi+$0], eax
      mov   [edi+$4], ebx
      mov   [edi+$8], ecx
      mov   [edi+$c], edx
      pop   edi
      pop   ebx
    {$ELSEIF Defined(CPUX64)}
      mov   r9,rcx
      mov   ecx,r8d
      mov   r8,rbx
      mov   eax,edx
      cpuid
      mov   [r9+$0], eax
      mov   [r9+$4], ebx
      mov   [r9+$8], ecx
      mov   [r9+$c], edx
      mov   rbx, r8
    {$ELSE}
      {$Message Fatal 'GetCPUID has not been implemented for this architecture.'}
    {$IFEND}
    end;
    
    function GetCPUName : String;
    
    var
      ExtPI : UInt32;
      CpuName: array[0..47] of Ansichar;
      CPUID : TCPUID;
    
    begin
     Result := '';
     Fillchar(CpuName[0], 48, 0);
     // INPUT EAX = 80000000H: Returns CPUID’s Highest Value for Extended Processor Information in EAX
     CPUID := GetCPUID($80000000, 0);
     ExtPI:= CPUID.rEAX;
     // 80000002H-80000004H EAX Processor Brand String. EBX Processor Brand String Continued. ECX Processor Brand String Continued. EDX Processor Brand String Continued.
     if ExtPI <> $80000001  then
      begin
       CPUID := GetCPUID($80000002, 0);
       Move(CPUID, CpuName[0], 16);
      end;
     if ExtPI <> $80000002  then
      begin
       CPUID := GetCPUID($80000003, 0);
       Move(CPUID, CpuName[16], 16);
      end;
     if ExtPI <> $80000003  then
      begin
       CPUID := GetCPUID($80000004, 0);
       Move(CPUID, CpuName[32], 16);
      end;
     Result := CpuName;
    end;
    
    
    begin
      try
       Writeln(GetCPUName);
       Readln;
      except
        on E: Exception do
          Writeln(E.ClassName, ': ', E.Message);
      end;
    end.
    

    For reference, GetCPUID function has been taken from @DavidHeffernan's excellent answer