Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows 如何获取USB闪存驱动器的制造商序列号?_Windows_Delphi_Usb - Fatal编程技术网

Windows 如何获取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

如何在Delphi中检索USB闪存驱动器的制造商序列号

我试过这个:

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);
to
ColDiskDrive:=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.