4

我试图弄清楚如何检测驱动器是否是大容量存储设备。我可以获得驱动器号,但无法弄清楚如何检测它是哪种设备。我正在尝试检测 Garmin GPS 接收器是否以大容量存储模式连接到 PC。

4

1 回答 1

5

您可以将WMI用于此任务,存在几个可以帮助您确定该信息的类,从Win32_USBHub检查Mass Storage Device属性Description中的值开始,还可以查看Win32_PNPEntity该类。如果您没有从 Delphi 访问 WMI 的经验,请尝试使用Wmi delphi 代码创建器

更新

要将 Win32_USBHub 或 Win32_USBControllerDevice WMI 类返回的值与磁盘驱动器号相关联,您必须执行以下步骤

  1. 查询 Win32_USBControllerDevice 类。
  2. 使用DeviceID提取的dependent每个返回实例(记录)的属性,使用 WQL 语句检查与 Win32_DiskDrive 相关的 Win32_PnPEntity 类,如下所示:ASSOCIATORS OF {Win32_PnPEntity.DeviceID="DeviceID"} WHERE ResultClass = Win32_DiskDrive
  3. 现在使用 Win32_DiskDriveToDiskPartition 类,您可以找到磁盘驱动器和分区之间的链接。
  4. 最后使用 Win32_LogicalDiskToPartition 类,您可以提取驱动器号。

检查此示例代码

{$APPTYPE CONSOLE}

{$R *.res}

uses
  Types,
  StrUtils,
  SysUtils,
  ActiveX,
  ComObj,
  Variants;

procedure ScanUSBPnpDevices;
const
  wbemFlagForwardOnly = $00000020;
var
  FSWbemLocator  : OLEVariant;
  objWMIService  : OLEVariant;

  USBControllerDevices: OLEVariant;
  USBControllerDevice : OLEVariant;
  EnumUSBDevice       : IEnumvariant;

  PnPEntities         : OLEVariant;
  PnPEntity           : OLEVariant;
  EnumPnPEntity       : IEnumvariant;

  DiskDrives          : OLEVariant;
  DiskDrive           : OLEVariant;
  EnumDiskDrive       : IEnumvariant;

  DiskPartitions      : OLEVariant;
  DiskPartition       : OLEVariant;
  EnumDiskPartition   : IEnumvariant;

  iValue         : LongWord;
  DeviceID       : string;
  DiskDeviceID   : string;
  DiskPartID     : string;

  StringDynArray : TStringDynArray;
begin;
  FSWbemLocator   := CreateOleObject('WbemScripting.SWbemLocator');
  objWMIService   := FSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', '');
  //This will scan all the usb device, you can filter this WQL sentece using any property of this class, to speed-up the process.
  USBControllerDevices := objWMIService.ExecQuery('SELECT Dependent FROM Win32_USBControllerDevice','WQL',wbemFlagForwardOnly);
  EnumUSBDEvice        := IUnknown(USBControllerDevices._NewEnum) as IEnumVariant;
  while EnumUSBDEvice.Next(1, USBControllerDevice, iValue) = 0 do
  begin
    StringDynArray:=SplitString(USBControllerDevice.Dependent, '=');
    DeviceID:=StringDynArray[1];
    Writeln(Format('USB Controller Device Device ID %s',[DeviceID]));
    PnPEntities     := objWMIService.ExecQuery(Format('ASSOCIATORS OF {Win32_PnPEntity.DeviceID=%s} WHERE ResultClass = Win32_DiskDrive',[DeviceID]),'WQL',wbemFlagForwardOnly);
    EnumPnPEntity   := IUnknown(PnPEntities._NewEnum) as IEnumVariant;
    while EnumPnPEntity.Next(1, PnPEntity, iValue) = 0 do
    begin
      //Escape the `\` chars in the DeviceID value because the '\' is a reserved character in WMI.
      DiskDeviceID   := PnPEntity.DeviceId;
      Writeln(Format('  Disk Drive Device ID %s',[DiskDeviceID]));
      DiskDeviceID   := StringReplace(DiskDeviceID,'\','\\',[rfReplaceAll]);;
      DiskDrives     := objWMIService.ExecQuery(Format('ASSOCIATORS OF {Win32_DiskDrive.DeviceID="%s"} WHERE AssocClass = Win32_DiskDriveToDiskPartition',[DiskDeviceID]),'WQL',wbemFlagForwardOnly);
      EnumDiskDrive  := IUnknown(DiskDrives._NewEnum) as IEnumVariant;
      while EnumDiskDrive.Next(1, DiskDrive, iValue) = 0 do
      begin
        DiskPartID:=DiskDrive.deviceID;
        Writeln(Format('    Disk Partition ID %s',[DiskPartID]));
        DiskPartitions:=objWMIService.ExecQuery(Format('ASSOCIATORS OF {Win32_DiskPartition.DeviceID="%s"} WHERE AssocClass = Win32_LogicalDiskToPartition',[DiskPartID]),'WQL',wbemFlagForwardOnly);
        EnumDiskPartition  := IUnknown(DiskPartitions._NewEnum) as IEnumVariant;
        while EnumDiskPartition.Next(1, DiskPartition, iValue) = 0 do
        begin
           Writeln(Format('      Drive Letter %s',[String(DiskPartition.DeviceID)]));
           DiskPartition:=Unassigned;
        end;
        DiskDrive:=Unassigned;
      end;
      PnPEntity:=Unassigned;
    end;
    USBControllerDevice:=Unassigned;
  end;
end;

begin
 try
    CoInitialize(nil);
    try
      ScanUSBPnpDevices;
    finally
      CoUninitialize;
    end;
 except
    on E:Exception do
        Writeln(E.Classname, ':', E.Message);
 end;
  Readln;
end.

这将返回这样的东西。

USB Controller Device Device ID "USBSTOR\\DISK&VEN_HP&PROD_V100W&REV_1.00\\3S980
62800DD&0"
  Disk Drive Device ID \\.\PHYSICALDRIVE1
    Disk Partition ID Disk #1, Partition #0
      Drive Letter F:
于 2012-03-02T08:38:49.923 回答