Windows 如何获取USB闪存驱动器的制造商序列号?
如何在Delphi中检索USB闪存驱动器的制造商序列号 我试过这个:Windows 如何获取USB闪存驱动器的制造商序列号?,windows,delphi,usb,Windows,Delphi,Usb,如何在Delphi中检索USB闪存驱动器的制造商序列号 我试过这个: function GetDiskVolSerialID(ADriveName: Char): Cardinal; var DiskDrive: string; FileSystemFlags: DWORD; VolumeSerialNumber: DWORD; MaximumComponentLength: DWORD; begin DiskDrive := ADriveName + ':\'; Get
function GetDiskVolSerialID(ADriveName: Char): Cardinal;
var
DiskDrive: string;
FileSystemFlags: DWORD;
VolumeSerialNumber: DWORD;
MaximumComponentLength: DWORD;
begin
DiskDrive := ADriveName + ':\';
GetVolumeInformation(PChar(DiskDrive),
nil,
0,
@VolumeSerialNumber,
MaximumComponentLength,
FileSystemFlags,
nil,
0);
Result := VolumeSerialNumber;
end;
但它不会返回正确的结果 opc0de,根据您的评论我将使用WMI为您提供一个示例 首先,您发布的代码(使用函数)返回格式化磁盘时windows分配的序列号 好消息是,存在两个wmi类,它们公开了一个名为
SerialNumber
的属性,该属性存储制造商为标识物理介质而分配的编号。这些类是和
现在坏消息是,不幸的是,这些类与逻辑磁盘的字母(C、D、E、F…)没有直接关联,因为您必须调用另一个wmi类来查找逻辑驱动器字母和物理驱动器之间的链接
因此,您必须找到此链接才能获得序列号。查找此关联的顺序如下所示
->->
这是使用类获取usb序列号的代码
顺便说一下,不久前我编写了一个名为的应用程序,它可以帮助您生成delphi代码,以便使用WMI访问系统信息
更新
USB磁盘的某些驱动程序不公开Win32_DiskDrive.SerialNumber属性上的制造商序列号,因此在这种情况下,您可以从PnPDeviceID
属性中提取序列号
检查此示例代码
{$APPTYPE CONSOLE}
uses
SysUtils,
StrUtils,
ActiveX,
ComObj,
Variants;
function VarStrNull(const V:OleVariant):string; //avoid issues with null variants
begin
Result:='';
if not VarIsNull(V) then
Result:=VarToStr(V);
end;
function GetUsbDriveSerial(const Drive:AnsiChar):string;
var
FSWbemLocator : OleVariant;
objWMIService : OLEVariant;
colDiskDrives : OLEVariant;
colLogicalDisks: OLEVariant;
colPartitions : OLEVariant;
objDiskDrive : OLEVariant;
objPartition : OLEVariant;
objLogicalDisk : OLEVariant;
oEnumDiskDrive : IEnumvariant;
oEnumPartition : IEnumvariant;
oEnumLogical : IEnumvariant;
iValue : LongWord;
DeviceID : string;
begin;
Result:='';
FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
objWMIService := FSWbemLocator.ConnectServer('.', 'root\CIMV2', '', '');
colDiskDrives := objWMIService.ExecQuery('SELECT * FROM Win32_DiskDrive WHERE InterfaceType="USB"','WQL',0);
oEnumDiskDrive:= IUnknown(colDiskDrives._NewEnum) as IEnumVariant;
while oEnumDiskDrive.Next(1, objDiskDrive, iValue) = 0 do
begin
DeviceID := StringReplace(VarStrNull(objDiskDrive.DeviceID),'\','\\',[rfReplaceAll]); //Escape the `\` chars in the DeviceID value because the '\' is a reserved character in WMI.
colPartitions := objWMIService.ExecQuery(Format('ASSOCIATORS OF {Win32_DiskDrive.DeviceID="%s"} WHERE AssocClass = Win32_DiskDriveToDiskPartition',[DeviceID]));//link the Win32_DiskDrive class with the Win32_DiskDriveToDiskPartition class
oEnumPartition := IUnknown(colPartitions._NewEnum) as IEnumVariant;
while oEnumPartition.Next(1, objPartition, iValue) = 0 do
begin
colLogicalDisks := objWMIService.ExecQuery('ASSOCIATORS OF {Win32_DiskPartition.DeviceID="'+VarStrNull(objPartition.DeviceID)+'"} WHERE AssocClass = Win32_LogicalDiskToPartition'); //link the Win32_DiskPartition class with theWin32_LogicalDiskToPartition class.
oEnumLogical := IUnknown(colLogicalDisks._NewEnum) as IEnumVariant;
while oEnumLogical.Next(1, objLogicalDisk, iValue) = 0 do
begin
if SameText(VarStrNull(objLogicalDisk.DeviceID),Drive+':') then //compare the device id
begin
Result:=VarStrNull(objDiskDrive.PnPDeviceID);
if AnsiStartsText('USBSTOR', Result) then
begin
iValue:=LastDelimiter('\', Result);
Result:=Copy(Result, iValue+1, Length(Result));
end;
objLogicalDisk:=Unassigned;
Exit;
end;
objLogicalDisk:=Unassigned;
end;
objPartition:=Unassigned;
end;
objDiskDrive:=Unassigned;
end;
end;
begin
try
CoInitialize(nil);
try
Writeln(GetUsbDriveSerial('F'));
Readln;
finally
CoUninitialize;
end;
except
on E:Exception do
begin
Writeln(E.Classname, ':', E.Message);
Readln;
end;
end;
end.
您可以尝试使用组件获取序列号。它不使用WMI,但在某些系统(磁盘类型)中无法检索号码。
试试看。它是免费的
注意。您想要格式化硬盘时windows分配的序列号还是制造商提供的序列号?制造商提供的序列号!WMI是为了方便访问包括硬件在内的信息系统而创建的,WMI是完成此类任务的完美工具,因为它的使用非常简单。我不知道你不使用WMI的动机是什么。你能解释一下吗?我尝试过用delphi实现它,但失败了,如果你有一些代码,我将不胜感激;)我也同意你的看法。您是否同意删除WMI约束?如果没有,还有其他原因吗?您请求帮助以满足一个可能会使其变得更困难的人为要求,因为您认为这应该更容易。在运行代码时,我出现了以下异常:无效查询任何IDEA为什么?好的,这是由于您的WMI版本更改此行
colDiskDrives:=objWMIService.ExecQuery('SELECT DeviceID,SerialNumber FROM Win32_DiskDrive WHERE InterfaceType=“USB”,'WQL',0);
toColDiskDrive:=objWMIService.ExecQuery('SELECT*FROM Win32_DiskDrive WHERE InterfaceType=“USB”,'WQL',0)
该代码已编辑为兼容旧版本的WMI。这是因为USB磁盘的某些驱动程序未公开Win32_DiskDrive.SerialNumber属性上的制造商序列号。@JustMarc,1。)是的,允许您在代码中使用此示例,2)技术上可能伪造序列号,为了避免这种情况,您可以尝试使用处理器、BIOS、RAM等硬件信息的组合。例如,请尝试使用此链接
{$APPTYPE CONSOLE}
uses
SysUtils,
StrUtils,
ActiveX,
ComObj,
Variants;
function VarStrNull(const V:OleVariant):string; //avoid issues with null variants
begin
Result:='';
if not VarIsNull(V) then
Result:=VarToStr(V);
end;
function GetUsbDriveSerial(const Drive:AnsiChar):string;
var
FSWbemLocator : OleVariant;
objWMIService : OLEVariant;
colDiskDrives : OLEVariant;
colLogicalDisks: OLEVariant;
colPartitions : OLEVariant;
objDiskDrive : OLEVariant;
objPartition : OLEVariant;
objLogicalDisk : OLEVariant;
oEnumDiskDrive : IEnumvariant;
oEnumPartition : IEnumvariant;
oEnumLogical : IEnumvariant;
iValue : LongWord;
DeviceID : string;
begin;
Result:='';
FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
objWMIService := FSWbemLocator.ConnectServer('.', 'root\CIMV2', '', '');
colDiskDrives := objWMIService.ExecQuery('SELECT * FROM Win32_DiskDrive WHERE InterfaceType="USB"','WQL',0);
oEnumDiskDrive:= IUnknown(colDiskDrives._NewEnum) as IEnumVariant;
while oEnumDiskDrive.Next(1, objDiskDrive, iValue) = 0 do
begin
DeviceID := StringReplace(VarStrNull(objDiskDrive.DeviceID),'\','\\',[rfReplaceAll]); //Escape the `\` chars in the DeviceID value because the '\' is a reserved character in WMI.
colPartitions := objWMIService.ExecQuery(Format('ASSOCIATORS OF {Win32_DiskDrive.DeviceID="%s"} WHERE AssocClass = Win32_DiskDriveToDiskPartition',[DeviceID]));//link the Win32_DiskDrive class with the Win32_DiskDriveToDiskPartition class
oEnumPartition := IUnknown(colPartitions._NewEnum) as IEnumVariant;
while oEnumPartition.Next(1, objPartition, iValue) = 0 do
begin
colLogicalDisks := objWMIService.ExecQuery('ASSOCIATORS OF {Win32_DiskPartition.DeviceID="'+VarStrNull(objPartition.DeviceID)+'"} WHERE AssocClass = Win32_LogicalDiskToPartition'); //link the Win32_DiskPartition class with theWin32_LogicalDiskToPartition class.
oEnumLogical := IUnknown(colLogicalDisks._NewEnum) as IEnumVariant;
while oEnumLogical.Next(1, objLogicalDisk, iValue) = 0 do
begin
if SameText(VarStrNull(objLogicalDisk.DeviceID),Drive+':') then //compare the device id
begin
Result:=VarStrNull(objDiskDrive.PnPDeviceID);
if AnsiStartsText('USBSTOR', Result) then
begin
iValue:=LastDelimiter('\', Result);
Result:=Copy(Result, iValue+1, Length(Result));
end;
objLogicalDisk:=Unassigned;
Exit;
end;
objLogicalDisk:=Unassigned;
end;
objPartition:=Unassigned;
end;
objDiskDrive:=Unassigned;
end;
end;
begin
try
CoInitialize(nil);
try
Writeln(GetUsbDriveSerial('F'));
Readln;
finally
CoUninitialize;
end;
except
on E:Exception do
begin
Writeln(E.Classname, ':', E.Message);
Readln;
end;
end;
end.