0

我正在尝试使用其驱动器号获取一些有效的代码来获取 USB 驱动器的供应商、序列号和型号。我搜索了很多并找到了几种解决方案。但我无法确定哪一个是最好的。

第一个在这里。使用 JEDI 的 hid.pas,但我不知道如何将它与单个驱动器一起使用。特别是,功能GetHidDeviceInfo非常有趣,但需要符号链接而不是驱动器号。我试图邀请驱动器号的符号链接无济于事。

第二个在这里。使用看起来不是很干净的 WMI。我的经验告诉我,WMI 并不适用于所有 PC。该代码在我自己的笔记本电脑上不起作用,显示“RPC 服务器不可用”。

请就实现目标的最佳方式向我提出建议。还有其他方法吗?

更新:我发布了一些示例代码,结合了下面评论的结果。

{$APPTYPE CONSOLE}

uses
  Windows, Messages, SysUtils, Variants;

type
  PHIDDAttributes = ^THIDDAttributes;
  HIDD_ATTRIBUTES = record
    Size:          ULONG; // size of structure (set before call)
    VendorID:      Word;
    ProductID:     Word;
    VersionNumber: Word;
    //
    // Additional fields will be added to the end of this structure.
    //
  end;
  THIDDAttributes = HIDD_ATTRIBUTES;

  THIDUSBDeviceInfo = Record   { contains interface level information of each device}
    SymLink            : String;
    BufferSize         : Word;
    Handle             : THandle;
    VID                : DWord;
    PID                : DWord;
    VersionNumber      : Word;
    ManufacturerString : String;
    ProductString      : String;
    SerialNumberString : String;
end;

function GetVolumeNameForVolumeMountPointW(const lpszVolumeMountPoint: LPCWSTR;
  lpszVolumeName: LPWSTR; cchBufferLength: DWORD): BOOL; stdcall;
  external kernel32;

function HidD_GetAttributes(HidDeviceObject: THandle;
  var HidAttrs: THIDDAttributes): LongBool; stdcall;external 'hid.dll' name 'HidD_GetAttributes';
function HidD_GetManufacturerString(HidDeviceObject: THandle;
  Buffer: PWideChar; BufferLength: Integer): LongBool; stdcall;external 'hid.dll' name 'HidD_GetManufacturerString';
function HidD_GetProductString(HidDeviceObject: THandle;
  Buffer: PWideChar; BufferLength: Integer): LongBool; stdcall;external 'hid.dll' name 'HidD_GetProductString';
function HidD_GetSerialNumberString(HidDeviceObject: THandle;
  Buffer: PWideChar; BufferLength: Integer): LongBool; stdcall;external 'hid.dll' name 'HidD_GetSerialNumberString';

function GetVolumeName(Name: string): string;
var
  Volume: array [0..MAX_PATH] of Char;
begin
  FillChar(Volume[0], SizeOf(Volume), 0);
  GetVolumeNameForVolumeMountPointW(PChar(Name), @Volume[0], SizeOf(Volume));
  Result := Volume;
end;

Function GetHidDeviceInfo( Symlink : PChar) : THIDUSBDeviceInfo;
  Var
    pstr          : pWideChar;
    DevHandle    : THandle;
    HidAttrs     : THIDDAttributes;
  Begin
    FillChar(Result, SizeOf( Result), 0);
    Result.SymLink := SymLink+ #0;
    GetMem( pstr, 512);
    DevHandle := CreateFile( Symlink,
                             GENERIC_READ or GENERIC_WRITE,
                             FILE_SHARE_READ or FILE_SHARE_WRITE,
                             nil,
                             OPEN_EXISTING,
                             0,
                             0);
    If DevHandle <> INVALID_HANDLE_VALUE then
    begin
      If HidD_GetAttributes( DevHandle,HidAttrs) then
      begin
        result.VID           := HidAttrs.VendorID;
        result.PID           := HidAttrs.ProductID;
        result.VersionNumber := HidAttrs.VersionNumber;
      end;

      If HidD_GetManufacturerString( DevHandle, pstr, 512) then
        Result.ManufacturerString := pStr;

      If HidD_GetProductString( DevHandle, pstr, 512) then
        Result.ProductString := pStr;

      If HidD_GetSerialNumberString( DevHandle, pstr, 512) then
        Result.SerialNumberString := pStr;

      closeHandle( DevHandle);
    end;
    FreeMem( pStr);
  End;

procedure Main;
var
  VolumeName: string;
  info: THIDUSBDeviceInfo;
begin
  VolumeName:=GetVolumeName('i:\'); //assuming that I: is a USB drive
  info:=GetHidDeviceInfo(pchar(VolumeName));
  Writeln(info.SerialNumberString);
end;

begin
  Main;
  Readln;
end.
4

1 回答 1

1

您可以尝试使用 WMI 获取磁盘的序列号(以及更多信息)。

使用 WMI 和Win32_DiskDrive 类,您可以获得序列号。文档说:“Windows Server 2003 和 Windows XP:此属性不可用。”

在 Windows Vista 中,7/8 工作正常。

要尝试此方法是否适合您,请在 clubdelphi ftp 上尝试这个简单的演示(包括源代码和二进制文件)。在 Windows 7 中,您会获得如下信息:

在此处输入图像描述

如果您可以获得正确的序列号,则可以使用 WMI。

与 WMI 一起工作的好库是 Sourceforge 上的 GLibWMI。包括一个特定的组件 (DiskDriveInfo),您可以使用 0 个代码行。见演示。

在此处输入图像描述

问候

于 2014-04-29T09:03:34.843 回答