【问题标题】:Getting Manufacturer, Serial Number, Model from Drive Letter从驱动器号获取制造商、序列号、型号
【发布时间】:2013-11-04 08:32:55
【问题描述】:

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

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

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

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

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

{$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.

【问题讨论】:

  • 你真的是指符号链接吗?这听起来有点难以置信。
  • @DavidHeffernan 是的。真的是符号链接。看看那个函数的代码。
  • 我认为您不应该将 Joop Beunders 视为该主题的权威来源。更仔细地阅读代码。特别是这一行:SymbolicLink := PChar( @(pSpDidd^.DevicePath))
  • @DavidHeffernan 所以请帮助我使用该功能。谢谢。
  • 你的问题不就是如何从盘符中获取设备路径吗?

标签: delphi usb wmi


【解决方案1】:

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

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

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

要尝试此方法是否适合您,请尝试this simple demo on clubdelphi ftp(包括源代码和二进制文件)。在 Windows 7 中,您会获得如下信息:

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

WMI is GLibWMI on Sourceforge 一起工作的好图书馆。包括一个特定的组件 (DiskDriveInfo),您可以使用 0 个代码行。 见演示。

问候

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-16
    • 2018-05-15
    • 1970-01-01
    • 2020-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多