9

How do I get the motherboard ID or serial number from Delphi code?

Is there any example code or articles that I can look at?

dsolimano
  • 8,870
  • 3
  • 48
  • 63
radick
  • 401
  • 2
  • 6
  • 12

3 Answers3

19

try using the WMI Win32_BaseBoard Class .

see theses samples:

Option 1) before execute you need import the Microsoft WMIScripting Library from Component->Import Component and then select Import type library

program GetWMI_MotherBoardInfo;

{$APPTYPE CONSOLE}

uses
  ActiveX,
  Variants,
  SysUtils,
  WbemScripting_TLB in '..\..\..\Documents\RAD Studio\5.0\Imports\WbemScripting_TLB.pas';//


Function  GetMotherBoardSerial:string;
var
  WMIServices : ISWbemServices;
  Root        : ISWbemObjectSet;
  Item        : Variant;
begin
  WMIServices := CoSWbemLocator.Create.ConnectServer('.', 'root\cimv2','', '', '', '', 0, nil);
  Root  := WMIServices.ExecQuery('Select SerialNumber From Win32_BaseBoard','WQL', 0, nil);
  Item := Root.ItemIndex(0);
  Result:=VarToStr(Item.SerialNumber);
end;


begin
  try
    CoInitialize(nil);
    Writeln('Serial MotherBoard '+GetMotherBoardSerial);
    Readln;
    CoUninitialize;
  except
    on E:Exception do
    Begin
        CoUninitialize;
        Writeln(E.Classname, ': ', E.Message);
        Readln;
    End;
  end;
end.

Option 2) using OLEVariant, IBindCtx Interface and IMoniker Interface

program GetWMI_MotherBoardSerial;

{$APPTYPE CONSOLE}

uses
  SysUtils
  ,ActiveX
  ,ComObj
  ,Variants;


function GetMotherBoardSerial:String;
var
  objWMIService : OLEVariant;
  colItems      : OLEVariant;
  colItem       : OLEVariant;
  oEnum         : IEnumvariant;
  iValue        : LongWord;

  function GetWMIObject(const objectName: String): IDispatch;
  var
    chEaten: Integer;
    BindCtx: IBindCtx;
    Moniker: IMoniker;
  begin
    OleCheck(CreateBindCtx(0, bindCtx));
    OleCheck(MkParseDisplayName(BindCtx, StringToOleStr(objectName), chEaten, Moniker));
    OleCheck(Moniker.BindToObject(BindCtx, nil, IDispatch, Result));
  end;

begin
  Result:='';
  objWMIService := GetWMIObject('winmgmts:\\localhost\root\cimv2');
  colItems      := objWMIService.ExecQuery('SELECT SerialNumber FROM Win32_BaseBoard','WQL',0);
  oEnum         := IUnknown(colItems._NewEnum) as IEnumVariant;
  if oEnum.Next(1, colItem, iValue) = 0 then
  Result:=VarToStr(colItem.SerialNumber);
end;


begin
 try
    CoInitialize(nil);
    try
      Writeln('Serial MotherBoard '+GetMotherBoardSerial);
      Readln;
    finally
    CoUninitialize;
    end;
 except
    on E:Exception do
    Begin
        Writeln(E.Classname, ': ', E.Message);
        Readln;
    End;
  end;
end.
RRUZ
  • 134,889
  • 20
  • 356
  • 483
  • The only thing I didn't understand is 'winmgmts:\\localhost\root\cimv2' – Himadri Sep 07 '10 at 09:41
  • @PRUZ I check the same code in some other computer which returns 'none'. What's the matter with it? – Himadri Sep 07 '10 at 11:20
  • @himadri, the second code uses a Late Binding call, wich does not requires import the wmi library inside delphi, you can read more abot Late binding in this link http://word.mvps.org/faqs/interdev/earlyvslatebinding.htm – RRUZ Sep 07 '10 at 14:15
  • The `winmgmts:\\localhost\root\cimv2` is the namespace where is located the class `Win32_BaseBoard`, you can read more about wmi namespaces in this link http://msdn.microsoft.com/en-us/library/aa822575%28VS.85%29.aspx – RRUZ Sep 07 '10 at 14:18
  • @PRUZ And you know something about my second comment? that `I check the same code in some other computer which returns 'none'. What's the matter with it?` – Himadri Sep 08 '10 at 05:15
  • My PC gives the following result too: `To be filled by O.E.M.` – Eugene Mala Aug 18 '17 at 16:20
2

If you want show the MainBoard Serial, use this stuff. To show the Mainboard Number in Windows 10 query the following in the WMI Service:
wmic baseboard get product,Manufacturer,version,serialnumber

//USES: Winapi.ActiveX, System.Win.ComObj
function TForm2.GetMotherBoardSerial: string;
var
  objWMIService: OLEVariant;
  colItems: OLEVariant;
  colItem: OLEVariant;
  oEnum: IEnumvariant;
  iValue: Longword;
  function GetWMIObject(const objectName: string): IDispatch;
  var
    chEaten: Integer;
    BindCtx: IBindCtx;
    Moniker: IMoniker;
  begin
    OleCheck(CreateBindCtx(0, bindCtx));
    OleCheck(MkParseDisplayName(BindCtx, StringToOleStr(objectName),
      chEaten, Moniker));
    OleCheck(Moniker.BindToObject(BindCtx, nil, IDispatch, Result));
  end;
begin
  Result := '';
  objWMIService := GetWMIObject('winmgmts:\\localhost\root\cimv2');
  colItems :=
    objWMIService.ExecQuery('SELECT SerialNumber FROM Win32_BaseBoard', 'WQL', 0);
  oEnum := IUnknown(colItems._NewEnum) as IEnumVariant;
  if oEnum.Next(1, colItem,
    iValue) = 0 then
    Result := VarToStr(colItem.SerialNumber);
end;
TomC
  • 1,871
  • 1
  • 12
  • 18
-2

I got another solution:

function TForm1.GetSerialMotherBoard: String;
var
  a, b, c, d: LongWord;
begin
  asm
    push EAX
    push EBX
    push ECX
    push EDX

    mov eax, 1
    db $0F, $A2
    mov a, EAX
    mov b, EBX
    mov c, ECX
    mov d, EDX

    pop EDX
    pop ECX
    pop EBX
    pop EAX

  end;
  result := inttohex(a, 8) + '-' +
            inttohex(b, 8) + '-' +
            inttohex(c, 8) + '-' +
            inttohex(d, 8);
end;
Dharman
  • 30,962
  • 25
  • 85
  • 135
  • Can you explain what your code is doing? Are you sure it returns motherboard serial number, but not CPUID? – Eugene Mala Aug 18 '17 at 16:23
  • I read a lot of issues about this and conclude that there is no ID for CPU and change my proposal to get HDD ID. My program above catches the same ID at different computers. – Wellington Telles Cunha Aug 22 '17 at 13:47
  • I think there is a problem with this function! I found that it returns different values each time the same program (in which it was used) runs on different starts. Examples (8 runs): 1) 000306D4-02100800-7FFAFBBF-BFEBFBFF, 2) 000306D4-00100800-7FFAFBBF-BFEBFBFF, 3) 000306D4-00100800-7FFAFBBF-BFEBFBFF, 4) 000306D4-02100800-7FFAFBBF-BFEBFBFF, 5) 000306D4-02100800-7FFAFBBF-BFEBFBFF, 6} 000306D4-03100800-7FFAFBBF-BFEBFBFF, 7) 000306D4-01100800-7FFAFBBF-BFEBFBFF, 8) 000306D4-00100800-7FFAFBBF-BFEBFBFF. Very strange! – jcfaria Jun 08 '20 at 00:01
  • I think that there is no solution... I have been trying since 2009. – Wellington Telles Cunha Jun 16 '20 at 14:25
  • 1
    @jcfaria The code shown is not retrieving the motherboard's ID. It is retrieving the CPU's model, family, stepping, branding, and feature details (not its actual serial number), and then concatenating those values together. The differences you are seeing are due to the `EBX` register getting a different value each time. Specifically, the bits corresponding to the "Local APIC ID", which is assigned a new value on each power up. See [CPU Identification](https://c9x.me/x86/html/file_module_x86_id_45.html) for more details. – Remy Lebeau Sep 23 '22 at 22:52