Search code examples
delphiwmi

Get Real HDD Serial Number with Delphi


I am trying to make delphi program Server And Client so To Secure my App and To Make Sure all user are under control i should give them a unique Key that can't be change to not lose them Handle, So i think it should be HDD Serial Number + Bios SN , but i remember that Bios Can Be Change When remove motherboard Battery so it will not be work . so my choose now is HDD Real serial number i am try this code below to get it but it didn'r work

    unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls,WbemScripting_TLB,ActiveX;

type
  TForm4 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form4: TForm4;

implementation

{$R *.dfm}

function GetWMIstring (wmiHost, wmiClass, wmiProperty : string):string;
var  // These are all needed for the WMI querying process
  Locator:  ISWbemLocator;
  Services: ISWbemServices;
  SObject:  ISWbemObject;
  ObjSet:   ISWbemObjectSet;
  SProp:    ISWbemProperty;
  Enum:     IEnumVariant;
  Value:    Cardinal;
  TempObj:  OleVariant;
  SN: string;
begin
  try
  Locator := CoSWbemLocator.Create;  // Create the Location object
  // Connect to the WMI service, with the root\cimv2 namespace
   Services :=  Locator.ConnectServer(wmiHost, 'root\cimv2', '', '', '','', 0, nil);
  ObjSet := Services.ExecQuery('SELECT * FROM '+wmiClass, 'WQL',
    wbemFlagReturnImmediately and wbemFlagForwardOnly , nil);
  Enum :=  (ObjSet._NewEnum) as IEnumVariant;
  while (Enum.Next(1, TempObj, Value) = S_OK) do
  begin
    SObject := IUnknown(tempObj) as ISWBemObject;
    SProp := SObject.Properties_.Item(wmiProperty, 0);
    if VarIsNull(SProp.Get_Value) then
      result := ''
    else
    begin
      SN := SProp.Get_Value;
      result :=  SN;
    end;
  end;
  except // Trap any exceptions (Not having WMI installed will cause one!)
   on exception do
    result := '';
   end;
end;

procedure TForm4.Button1Click(Sender: TObject);
var
x:string;
Y:string;

begin


    X:=GetWMIstring('','Win32_BIOS','SerialNumber');
    Y:=GetWMIstring('','Win32_DiskDrive"','SerialNumber')     ;

    ShowMessage(x+';'+y);
end;

end.

*so please can any one correct my Code or Give me another idea Best regard's*


Solution

  • Your code is not working because you are passing a double-quote in the WMI class name.

    change this code

    GetWMIstring('','Win32_DiskDrive"','SerialNumber');
    

    To this

    GetWMIstring('','Win32_DiskDrive','SerialNumber');
    

    Btw, you can improve a lot your WMI function (GetWMIstring) if you follow the recommendations of the answer to this question How can I improve the WMI performance using delphi?.

    Try this sample (this code use late binding and don't need the WbemScripting_TLB unit)

      uses
          ActiveX,
          ComObj;
    
        var
          FSWbemLocator : OLEVariant;
          FWMIService   : OLEVariant;
    
        function  GetWMIstring(const WMIClass, WMIProperty:string): string;
        const
          wbemFlagForwardOnly = $00000020;
        var
          FWbemObjectSet: OLEVariant;
          FWbemObject   : OLEVariant;
          oEnum         : IEnumvariant;
          iValue        : LongWord;
        begin;
          Result:='';
          FWbemObjectSet:= FWMIService.ExecQuery(Format('Select %s from %s',[WMIProperty, WMIClass]),'WQL',wbemFlagForwardOnly);
          oEnum         := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
          if oEnum.Next(1, FWbemObject, iValue) = 0 then
    
      if not VarIsNull(FWbemObject.Properties_.Item(WMIProperty).Value) then
    
         Result:=FWbemObject.Properties_.Item(WMIProperty).Value;
    
        FWbemObject:=Unassigned;
        end;
    
        procedure TForm4.Button1Click(Sender: TObject);
        var
          x:string;
          Y:string;
        begin
          FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
          FWMIService   := FSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', '');
    
          X:=GetWMIstring('Win32_BIOS','SerialNumber');
          Y:=GetWMIstring('Win32_PhysicalMedia','SerialNumber');
    
          ShowMessage(x+';'+y);
        end;