我正在尝试制作delphi程序服务器和客户端,以便保护我的应用程序并确保所有用户都在控制之下我应该给他们一个独特的密钥,不能改变不丢失他们处理,所以我认为它应该是硬盘序列号+ Bios SN,但我记得Bios可以更换当删除主板电池,所以它将无法正常工作。 所以我现在选择的是HDD Real序列号我试试这个代码来获得它但它没有工作
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.
* 所以请任何人更正我的代码或给我另一个想法 最好的关注 *
答案 0 :(得分:22)
您的代码无效,因为您在WMI类名称中传递了双引号。
更改此代码
GetWMIstring('','Win32_DiskDrive"','SerialNumber');
到此
GetWMIstring('','Win32_DiskDrive','SerialNumber');
顺便说一下,如果你按照这个问题How can I improve the WMI performance using delphi?
的答案的建议,你可以提高你的WMI功能(GetWMIstring)。
尝试此示例(此代码使用后期绑定,不需要WbemScripting_TLB
单位)
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;
答案 1 :(得分:0)
当安装更多设备时,您应该避免使用PHYSICALDRIVE0在数据库中不是第一个。 PHYSICALDRIVE1是我的第一个。我添加 where 进行查询,现在工作正常。对于Win32_DiskDrive,属性名称为 DeviceID ,对于Win32_PhysicalDrive,属性名称为标记。这里改变了部分:
function GetWMIstring(const WMIClass, WMIProperty, WMIWhere:string): string;
...
qry:='SELECT '+WMIProperty+' FROM '+WMIClass;
if WMIWhere<>'' then qry:=qry + ' WHERE '+WMIWhere;
FWbemObjectSet:= FWMIService.ExecQuery(qry,'WQL',wbemFlagForwardOnly);
...
x:=GetWMIstring('Win32_DiskDrive','SerialNumber','DeviceID="\\\\.\\PHYSICALDRIVE0"'));
y:=GetWMIstring('Win32_PhysicalMedia','SerialNumber','Tag="\\\\.\\PHYSICALDRIVE0"'));
/ 不要忘记在!!!之前打电话给CoInitialize