![]() |
Hardware ID erstellen
Bei The Road To Delphi habe ich was gefunden
![]() Gibt es vielleicht eine neuere weniger aggressive Möglichkeit eine Hardware ID zu erzeugen? Kann man diese Unit überhaupt noch verwenden? Ich bekomme immer einen leeren String zurück,.
Delphi-Quellcode:
unit HardwareIDGenerator;
interface uses System.Classes, System.SysUtils, Winapi.ActiveX, System.Win.ComObj, System.Variants; type TMotherBoardInfo = (Mb_SerialNumber, Mb_Manufacturer, Mb_Product, Mb_Model); TMotherBoardInfoSet = set of TMotherBoardInfo; TProcessorInfo = (Pr_Description, Pr_Manufacturer, Pr_Name, Pr_ProcessorId, Pr_UniqueId); TProcessorInfoSet = set of TProcessorInfo; TBIOSInfo = (Bs_BIOSVersion, Bs_BuildNumber, Bs_Description, Bs_Manufacturer, Bs_Name, Bs_SerialNumber, Bs_Version); TBIOSInfoSet = set of TBIOSInfo; TOSInfo = (Os_BuildNumber, Os_BuildType, Os_Manufacturer, Os_Name, Os_SerialNumber, Os_Version); TOSInfoSet = set of TOSInfo; const // properties names to get the data MotherBoardInfoArr: array [TMotherBoardInfo] of AnsiString = ('SerialNumber', 'Manufacturer', 'Product', 'Model'); OsInfoArr: array [TOSInfo] of AnsiString = ('BuildNumber', 'BuildType', 'Manufacturer', 'Name', 'SerialNumber', 'Version'); BiosInfoArr: array [TBIOSInfo] of AnsiString = ('BIOSVersion', 'BuildNumber', 'Description', 'Manufacturer', 'Name', 'SerialNumber', 'Version'); ProcessorInfoArr: array [TProcessorInfo] of AnsiString = ('Description', 'Manufacturer', 'Name', 'ProcessorId', 'UniqueId'); type THardwareId = class private FOSInfo: TOSInfoSet; FBIOSInfo: TBIOSInfoSet; FProcessorInfo: TProcessorInfoSet; FMotherBoardInfo: TMotherBoardInfoSet; FBuffer: AnsiString; function GetHardwareIdHex: AnsiString; public // Set the properties to be used in the generation of the hardware id property MotherBoardInfo: TMotherBoardInfoSet read FMotherBoardInfo write FMotherBoardInfo; property ProcessorInfo: TProcessorInfoSet read FProcessorInfo write FProcessorInfo; property BIOSInfo: TBIOSInfoSet read FBIOSInfo write FBIOSInfo; property OSInfo: TOSInfoSet read FOSInfo write FOSInfo; property Buffer: AnsiString read FBuffer; // return the content of the data collected in the system property HardwareIdHex: AnsiString read GetHardwareIdHex; // get a hexadecimal represntation of the data collected procedure GenerateHardwareId; // calculate the hardware id constructor Create(Generate: Boolean = True); overload; Destructor Destroy; override; end; implementation function VarArrayToStr(const vArray: variant): AnsiString; function _VarToStr(const V: variant): AnsiString; var Vt: integer; begin Vt := VarType(V); case Vt of varSmallint, varInteger: Result := AnsiString(IntToStr(integer(V))); varSingle, varDouble, varCurrency: Result := AnsiString(FloatToStr(Double(V))); varDate: Result := AnsiString(VarToStr(V)); varOleStr: Result := AnsiString(WideString(V)); varBoolean: Result := AnsiString(VarToStr(V)); varVariant: Result := AnsiString(VarToStr(variant(V))); varByte: Result := AnsiChar(byte(V)); varString: Result := AnsiString(V); varArray: Result := VarArrayToStr(variant(V)); end; end; var i: integer; begin Result := '['; if (VarType(vArray) and varArray) = 0 then Result := _VarToStr(vArray) else for i := VarArrayLowBound(vArray, 1) to VarArrayHighBound(vArray, 1) do if i = VarArrayLowBound(vArray, 1) then Result := Result + _VarToStr(vArray[i]) else Result := Result + '|' + _VarToStr(vArray[i]); Result := Result + ']'; end; function VarStrNull(const V: OleVariant): AnsiString; // avoid problems with null strings begin Result := ''; if not VarIsNull(V) then begin if VarIsArray(V) then Result := VarArrayToStr(V) else Result := AnsiString(VarToStr(V)); end; end; {THardwareId} constructor THardwareId.Create(Generate: Boolean = True); begin inherited Create; CoInitialize(nil); FBuffer := ''; // Set the propeties to be used in the hardware id generation FMotherBoardInfo := [Mb_SerialNumber, Mb_Manufacturer, Mb_Product, Mb_Model]; FOSInfo := [Os_BuildNumber, Os_BuildType, Os_Manufacturer, Os_Name, Os_SerialNumber, Os_Version]; FBIOSInfo := [Bs_BIOSVersion, Bs_BuildNumber, Bs_Description, Bs_Manufacturer, Bs_Name, Bs_SerialNumber, Bs_Version]; FProcessorInfo := []; // including the processor info is expensive [Pr_Description,Pr_Manufacturer,Pr_Name,Pr_ProcessorId,Pr_UniqueId]; if Generate then GenerateHardwareId; end; destructor THardwareId.Destroy; begin CoUninitialize; inherited; end; // Main function which collect the system data. procedure THardwareId.GenerateHardwareId; var objSWbemLocator: OleVariant; objWMIService: OleVariant; objWbemObjectSet: OleVariant; oWmiObject: OleVariant; oEnum: IEnumvariant; iValue: LongWord; SDummy: AnsiString; Mb: TMotherBoardInfo; Os: TOSInfo; Bs: TBIOSInfo; Pr: TProcessorInfo; begin; objSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator'); objWMIService := objSWbemLocator.ConnectServer('localhost', 'root\cimv2', '', ''); if FMotherBoardInfo <> [] then // MotherBoard info begin objWbemObjectSet := objWMIService.ExecQuery('SELECT * FROM Win32_BaseBoard', 'WQL', 0); oEnum := IUnknown(objWbemObjectSet._NewEnum) as IEnumvariant; while oEnum.Next(1, oWmiObject, iValue) = 0 do begin for Mb := Low(TMotherBoardInfo) to High(TMotherBoardInfo) do if Mb in FMotherBoardInfo then begin SDummy := VarStrNull(oWmiObject.Properties_.Item(MotherBoardInfoArr[Mb]).Value); FBuffer := FBuffer + SDummy; end; oWmiObject := Unassigned; end; end; if FOSInfo <> [] then // Windows info begin objWbemObjectSet := objWMIService.ExecQuery('SELECT * FROM Win32_OperatingSystem', 'WQL', 0); oEnum := IUnknown(objWbemObjectSet._NewEnum) as IEnumvariant; while oEnum.Next(1, oWmiObject, iValue) = 0 do begin for Os := Low(TOSInfo) to High(TOSInfo) do if Os in FOSInfo then begin SDummy := VarStrNull(oWmiObject.Properties_.Item(OsInfoArr[Os]).Value); FBuffer := FBuffer + SDummy; end; oWmiObject := Unassigned; end; end; if FBIOSInfo <> [] then // BIOS info begin objWbemObjectSet := objWMIService.ExecQuery('SELECT * FROM Win32_BIOS', 'WQL', 0); oEnum := IUnknown(objWbemObjectSet._NewEnum) as IEnumvariant; while oEnum.Next(1, oWmiObject, iValue) = 0 do begin for Bs := Low(TBIOSInfo) to High(TBIOSInfo) do if Bs in FBIOSInfo then begin SDummy := VarStrNull(oWmiObject.Properties_.Item(BiosInfoArr[Bs]).Value); FBuffer := FBuffer + SDummy; end; oWmiObject := Unassigned; end; end; if FProcessorInfo <> [] then // CPU info begin objWbemObjectSet := objWMIService.ExecQuery('SELECT * FROM Win32_Processor', 'WQL', 0); oEnum := IUnknown(objWbemObjectSet._NewEnum) as IEnumvariant; while oEnum.Next(1, oWmiObject, iValue) = 0 do begin for Pr := Low(TProcessorInfo) to High(TProcessorInfo) do if Pr in FProcessorInfo then begin SDummy := VarStrNull(oWmiObject.Properties_.Item(ProcessorInfoArr[Pr]).Value); FBuffer := FBuffer + SDummy; end; oWmiObject := Unassigned; end; end; end; function THardwareId.GetHardwareIdHex: AnsiString; begin SetLength(Result, Length(FBuffer) * 2); BinToHex(PAnsiChar(FBuffer), PAnsiChar(Result), Length(FBuffer)); end; end. |
AW: Hardware ID erstellen
Nun ja, prinzipiell ist eine Hardware-ID immer problematisch. (Habe 20-30 Jahre Erfahrung damit)
Was ist wenn Komponenten ausgetauscht werden? Was ist mit virtuellen Maschinen? |
AW: Hardware ID erstellen
Ich habe auch schon den Fall gehabt, dass Nutzer mit unterschiedlichen Zugriffsrechten scheinbar nicht immer Zugriff auf die WMI Funktionen haben und dadurch nichts generiert wurde. Es gibt auch eine HardwareId.dll, die allerdings in Versuchen am gleichen Rechner nach jedem neustart zwischen verschiedenen Ids rumgesprungen ist. Also solange der Rechner nicht neu getsartet wrde, blieb die ID dieselbe, aber nach einem Neustart war es ein Lottospiel.
|
AW: Hardware ID erstellen
Das Anwendungsgebiet dieses kleinen Programms ist in VMs eher unmöglich, da es von einer anderen 3D-Software abhängig ist, die in einer VM mit ziemlicher Sicherheit nicht korrekt lauffähig sein wird.
Ich erzeuge die ID jetzt so, ob das lasch genug ist?
Delphi-Quellcode:
Mainboard oder Prozessor müssten ausgetauscht werden, damit die ID ungültig wird. Das ist eher seltener der Fall denke ich.
HWID := THardwareId.Create(False);
try HWID.OSInfo := []; // Keinerlei Betriebssystem-Informationen HWID.BIOSInfo := []; // Keinerlei BIOS-Informationen HWID.GenerateHardwareId; ID := HWID.HardwareIdHex); finally HWID.Free; end; Zitat:
Wie könnte man sonst an eine relativ eindeutige ID kommen? Ist die einer CPU eindeutig? |
AW: Hardware ID erstellen
Das problem ist, dass eigentlich NICHTS eindeutig ist. Es gibt CPUs, welche keine CPUID zurückgeben, es gibt mainboards, welche keine Seriennummer haben, alles nur so wie 00000-000-0000-00000
Von daher.. :gruebel: |
AW: Hardware ID erstellen
Wie siehts denn mit der SerialNumber des Betriebssystems aus zusammen mit anderen Werten?
|
AW: Hardware ID erstellen
Ich glaube bei der Seriennummer des Betriebssystems zum Bsp. gibt Windows für diverse Hersteller wie Dell Sammelnummern raus und mehrere PC (also tausende) nutzen die gleiche Seriennummer. ich glaube, die kommt sogar direkt im BIOS, mein Windows Laptop hat immer sofort eine Seriennummer, wenn ich ihn installiere. selbst, als ich die festplatte getauscht habe und garnicht die Windows-version genommen habe, die original drauf war.
|
AW: Hardware ID erstellen
Also es muss nicht weltweit absolut eindeutig sein. Es sollte nur relativ eindeutig sein.
Würde da OS Seriennummer, Bios-Versions-String und Name des PCs sowie Nutzers nicht reichen? Oder reicht ganz simple die Seriennummer aller Laufwerke? |
AW: Hardware ID erstellen
Hmm..
Welche HardwareID soll es den sein? Der Client selber? - Wenn als FatClient läuft - Wenn auf Theminal Server aufgeschaltet (Wechseln eventuell bei jedem Login) - Wenn auf VirtualDesktop aufgeschaltet - Wenn als Host für eine VM Vom Therminalservern? Von der VM welche auf dem Client läuft? Durch Virtualisierung und TherminSessions sind alle Informationen wie Prozessor, MAC, Bios und Co einfach nicht 'Eindeutig'... (Aber ich glaube einen solchen Thread um eine System ID hatten wir schon öffters.. ;) ) |
AW: Hardware ID erstellen
Mein Programm soll ganz einfach nur eine ID erzeugen, die für dieses System mehr oder weniger eindeutig ist. Ob es jetzt unter 1 Millionen Systemen eins gibt mit derselben ID ist mir egal.
Und da ist die Frage, ob OS Seriennummer, PC-Name, Nutzer-name, BIOS-Versions-String und Festplatten-IDs nicht schon ausreichen. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:18 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz