![]() |
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. |
AW: Hardware ID erstellen
Hmm..
Zitat:
OS Seriennummer - Dürfte auf Terminserver mit Datacenter-Lizenz überall gleich sein... BIOS-Versions-String - wohl auch Festplatten-IDs - Die ID der virtuellen oder realen Festplatte, wenn überhaupt vorhanden? Nutzer-name - Dieser ist Schall und Rauch und wird eventuell an vielen PCs gleichzeitig verwendet. PC-Name - Diesen gibt es zu mindestens je Kunde nur einmal in seinem Netz. - Allerdings könnte es dann mit Virtual Desktops Probleme geben, da dort der Name immer beim rollout wechselt, bzw. alle Clients wechselnd auch immer wieder andere VD bekommen können.. Es ist somit nicht einfach ein System 'Eindeutig' zu identifizieren.. ;) Ein lokal benutzter FatClient, da kannst Du diese Hardsware-IDs (Serial HD/Bios/CPU..) 'grob' verwenden, aber wenn es virtual wird... dann ist es damit fast schon vorbei. |
AW: Hardware ID erstellen
Ich habe keine Ahnung was ein Terminserver sein soll aber ich kann dir sagen, dass mein Programm nur auf ganz normalen PCs läuft und niemals auf irgendwelchen Enterprise-Datacenter-Simsallabim-PCs.
|
AW: Hardware ID erstellen
Was möchtest Du mit der HardwareID erreichen? Registrierte Anwender sollen Deine Software einfacher erneut installieren können? Mit einem ausgewechselten Stück Hardware (SSD?) geht das in der Regel schon schief. Den PC des Anwenders als Dongle zu nutzen war mal eine populäre Sache, weswegen man ja auch bei Intel sogar Seriennummern in die CPU einbaute. Allerdings ist das 10 Jahre her, und seither haben sich viel zu viele gemeldet, die das nicht so toll fanden, und auch gute Gründe dafür gaben. Und austricksen lässt sich das mit VMs ohnehin allzu leicht.
Da Du ja ohnehin eine DB und Onlineverbindung dazu herstellen mußt, ist es viel einfacher, User und Registrierungsschlüssel abzufragen (so wie Embarcadero...nur eben besser, bitte), als irgendwelche HardwareIDs, die durch semiambitionierte Anwender geändert werden können, schlicht durch Austausch von ein bis zwei Komponenten. Wie bei jedem Kopierschutz möchte ich anregen, sehr genau darüber nachzudenken, ob Zeit und Aufwand, die in den Kopierschutz gesteckt werden, nicht besser im eigentlichen Programm aufgehoben sind. Höhere Qualität erzeugt zufriedenere Kunden, die wiederum die beste Werbung für ein Produkt sind, die man für Geld nicht kaufen kann. Sherlock |
AW: Hardware ID erstellen
Zitat:
|
AW: Hardware ID erstellen
Hmm..
Zitat:
Einen Terminserver hast Du schon dann, wenn Du dich per RDP auf einen anderen PC aufschaltets. Dann ist dieser automatisch der Terminalserver.... Im gewerblichen Bereich werden dort z.B. Citrix-Terminservewr verwendet, welche eine virtuelle Umgebung für viele Clients gleichzeitig bereitstellen. |
AW: Hardware ID erstellen
Solch einen Fall wird es bei mir definitiv niemals geben.
|
AW: Hardware ID erstellen
Hallo,
ich "hacke" mich mal frech hier rein :) In meiner Software verwende ich auch eine Hardware ID. Nicht wegen Kopierschutz, sondern wegen Zuordnung von Systemkonfiguration, Benutzererkennung, etc. Früher, so Windows XP, wurde mal gesagt, dass Windows eine Installations ID pro Installation erzeugt. Wo steht diese in der Registry bei Windows 10, oder gibt es das nicht mehr? Bei Benutzern legt Windows angeblich nicht nur den Namen, sondern auch eine eindeutige Sicherheitskennung an. Gibt es das auch noch bei Windows 10? Mir geht es nur darum, dass ich einen PC möglichst genau über interne Daten erkennen kann. Danke. Johndoe049 |
AW: Hardware ID erstellen
Meinst du die MachineGUID?
![]() Leider steht da nicht seit wann es das schon gibt. Das Bild sieht aber nach Windows 7 aus. Das sollte lange genug sein. Diese MachineGUID könnte man zusätzlich nehmen. Aber nur die würde ich nicht. Die kann man doch ändern? So wie da im dem Artikel steht würde ich aber auch nicht die Festplatten-Seriennummern nehmen. Das dauert sehr lange die Nummern per WMI zu sammeln. Fast 1 Sekunde bei mir trotz SSD und ordentlichem Prozessor. |
AW: Hardware ID erstellen
Vielleicht reicht es ja schon, in der Registry einen bestimmten Key anzulegen (pro User) und dort eine frisch erzeugte GUID reinzuschreiben? Die ist dann auch eindeutig pro Windows-Installation und User. (Es sei denn, jemand cloned die Platte.)
Ob das ausreicht, kommt auf den Anwendungsfall an. Als Kopierschutz reicht es nicht. |
AW: Hardware ID erstellen
In der Winapi.Windows gibt es die Methode "GetVolumeinformation". Damit lässt sich ohne großen Aufwand, und zudem sehr schnell, auch die Seriennummern der Laufwerke bestimmen. Man benötigt dafür keine WMI Abfrage.
Gruß Kompi |
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:08 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