Как я могу определить, подключено ли устройство Garmin GPS в режиме хранения? - PullRequest
3 голосов
/ 02 марта 2012

Я пытаюсь выяснить, как определить, является ли накопитель запоминающим устройством.Я могу получить буквы диска, но не могу понять, как определить, что это за устройство.Я пытаюсь определить, подключен ли GPS-приемник Garmin к ПК в режиме хранения.

1 Ответ

4 голосов
/ 02 марта 2012

Вы можете использовать WMI для этой задачи, существует несколько классов, которые могут помочь вам определить эту информацию, начиная с Win32_USBHub проверки значения Mass Storage Device всвойство Описание , также посмотрите в класс Win32_PNPEntity.Если у вас нет опыта доступа к WMI из Delphi, попробуйте использовать Wmi Delphi Code Creator

ОБНОВЛЕНИЕ

Чтобы связать возвращаемые значенияс помощью классов WMI Win32_USBHub или Win32_USBControllerDevice с буквой диска необходимо выполнить следующие шаги

  1. Запрос для класса Win32_USBControllerDevice.
  2. Использование DeviceID, извлеченного из dependent свойство каждого возвращаемого экземпляра (записи) проверяет класс Win32_PnPEntity, привязанный к Win32_DiskDrive, используя предложение WQL, например: 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:
...