[gelöst] HDD-Id über wmi immer eine Fehlermeldung

Für Fragen rund um die Ide und zum Debugger
Antworten
exc-jdbi
Beiträge: 64
Registriert: So 3. Aug 2014, 03:37

[gelöst] HDD-Id über wmi immer eine Fehlermeldung

Beitrag von exc-jdbi »

Guten Morgen Community

Ich bin ganz neu hier, und arbeite mich in die Lazarussprache ein.

Dazu hab ich mir die neuste Version (1.2.4) runtergeladen. Ich besitze Win Vista-32.

Zu meinem Problem.
Ich brauche die Hdd-Id oder die Motherboard-Id (jeweils die Seriennummer). Mit WMI hab ich das jetzt versucht, lauft bei mir aber extrem unstabil. Die Variabel "FWbemObject.DomainRole" besitzt immer den Wert <Error>.

Eingebunden habe ich:

Code: Alles auswählen

 
uses   SysUtils,   ActiveX,   ComObj,   Variants,   Windows;
 

Mein Code:

Code: Alles auswählen

 
procedure GetWin32_ComputerSystemInfo;
const
   WbemUser ='';
   WbemPassword ='';
   WbemComputer ='localhost';
   wbemFlagForwardOnly = $00000020;
var
   FSWbemLocator : OLEVariant;
   FWMIService : OLEVariant;
   FWbemObjectSet: OLEVariant;
   FWbemObject : Variant;
   oEnum : IEnumvariant;
   sValue : string;
 
begin;
   FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
   FWMIService := FSWbemLocator.ConnectServer(WbemComputer, 'root\CIMV2', WbemUser, WbemPassword);
   FWbemObjectSet:= FWMIService.ExecQuery('SELECT * FROM Win32_ComputerSystem','WQL',wbemFlagForwardOnly);
   oEnum := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
   while oEnum.Next(1, FWbemObject, nil) = 0 do
   begin
     case Integer(FWbemObject.DomainRole) of
       0: Writeln('Standalone Computer');
       //1: ....
       //2: ....
     end;
 
     Writeln('');
     FWbemObject:=Unassigned;
   end;
end;
 
Gesucht habe ich hier im Forum schon nach Möglichkeiten. Jedoch gefunden habe ich nichts passendes.

Kennt jemand dieses Problem? Versionsbedingt vielleicht?

Gibt es eventuell eine andere Möglichkeit die entsprechenden Id's zu ermitteln?

Danke für die Hilfe.

Freundliche Grüsse

exc-jdbi
Zuletzt geändert von exc-jdbi am So 5. Okt 2014, 13:39, insgesamt 1-mal geändert.

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: HDD-Id über wmi immer eine Fehlermeldung

Beitrag von Michl »

exc-jdbi hat geschrieben: Ich bin ganz neu hier, und arbeite mich in die Lazarussprache ein.
Das ist sehr schön, ich hoffe Du bist kein Bot, wenn nein, dann ein fröhliches Willkommen in Lazarusforum. PS: die Programmiersprache nennt sich Pascal.

Ich weiss nicht, was Du da gelesen hast, als Du den Code kopiert hast, die HDD-ID bekommst Du damit auf jeden Fall nicht, es ging um: Active Directory Controller in der Systemumgebung ermitteln

Bei mir funktioniert:
HDD-ID: http://lists.lazarus.freepascal.org/pip ... 35263.html
und
Motherboard-ID: http://stackoverflow.com/questions/2497 ... -in-delphi
ein bischen abgewandelt:

Code: Alles auswählen

uses Windows, 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: PULONG;
    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;
 
procedure TForm1.Button1Click(Sender: TObject);
begin
  ShowMessage('Serial MotherBoard: '+GetMotherBoardSerial);
end; 
PS: Alles Windows only, getestet habe ich unter Win7 64bit.

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

exc-jdbi
Beiträge: 64
Registriert: So 3. Aug 2014, 03:37

Re: HDD-Id über wmi immer eine Fehlermeldung

Beitrag von exc-jdbi »

Hallo Michl

Meinen Dank für die Antwort.

Das es sich hier um PAscal/Delphi handelt habe ich ziemlich schnell erkannt :wink:
Ich geh aber davon aus, dass es unterschiede gibt, die man zuerst kennenlernen und erkennen muss. In dieser Phase befinde ich mich wohl zurzeit.

Und tatsächlich ich hab Oben noch den falschen Code eingefügt, war wohl schon ziemlich späht bzw. früh.

Ich hab mir dein Beispiel ausprobiert. Hab noch ne Änderung angebracht damit es bei mir funktioniert. Leider weiss ich nicht ob das richtig ist.

Ich füg hier einfch mal den Code ein:

Code: Alles auswählen

 
program GetMotherBoardSerialAndGetVolumeID;
 
{$APPTYPE CONSOLE}
 
uses
  SysUtils, ActiveX, ComObj, Variants, windows;
 
function GetMotherBoardSerial:String;
var
  objWMIService : OLEVariant;
  colItems      : OLEVariant;
  colItem       : Variant;
  oEnum         : IEnumvariant;
  iValue        : LongWord;
 
  function GetWMIObject(const objectName: String): IDispatch;
  var
    chEaten: puLong;
    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;
 
function GetVolumeID(DriveChar: Char): String;
//Para obtener el # de serie de un disco
var
  MaxFileNameLength:dWord=0;
  VolFlags:dWord=0;
  SerNum: DWord;
  DrivePath : String;
begin
  DrivePath :=  DriveChar + ':\';
  if GetVolumeInformation(PChar(DrivePath), nil, 0,@SerNum, MaxFileNameLength, VolFlags, nil, 0)
  then
  begin
      Result := IntToStr(SerNum);
  end
  else
      Result := '';
end;
begin
 try
    CoInitialize(nil);
    try
      Writeln('Serial MotherBoard '+GetMotherBoardSerial);
      Writeln('Serial Volumen C '+GetVolumeID('C'));
      Readln;
    finally
    CoUninitialize;
    end;
 except
    on E:Exception do
    Begin
        Writeln(E.Classname, ': ', E.Message);
        Readln;
    End;
  end;
end.
 
Unter GetVolumeInformation hab ich der Variable iValue ein '@'-Zeichen hinzugefügt und der Variable chEaten hab ich wie du erwähnt hats den Typ puLong deklariert. Als ich das dann unter der function oEnum.Next zurückverfolgt habe, schien mir das ziemlich logisch.

Es funktioniert. :D Mit diesem Ansatz habe ich den ersten korrekten Schritt Richtung Hardware. WMI ist ja noch nicht dabei.

Um das obige Problem werde ich mich jetzt auch no schnell kümmer.


Nochmals Danke für die Mühe.

Freundliche Grüsse

exc-jdbi

Antworten