2012-03-01 24 views
3

ドライブが大容量記憶装置であるかどうかを検出する方法を理解しようとしています。私はドライブレターを手に入れることができますが、どのようなデバイスであるかを検出する方法を理解することはできません。 Garmin GPSレシーバが大容量記憶モードのPCに接続されているかどうかを検出しようとしています。Garmin GPSデバイスが大容量ストレージモードで接続されているかどうかを検出するにはどうすればよいですか?

+0

GPSデバイスはUSB経由で接続されていますか? – RRUZ

+0

はいそれはUSBデバイスです – colin

答えて

4

あなたは、このタスクのためWMIを使用し、その情報を決定するためにあなたを助けることができるいくつかのクラスを存在し、Win32_USBHubが財産説明に値Mass Storage Deviceのチェックを開始し、またWin32_PNPEntityクラスで見てみることができます。あなたは、DelphiからWMIをaccesing経験を持っていない場合は、ディスクドライブ文字とWin32_USBHubまたはWin32_USBControllerDevice WMIクラスによって返された値を関連付けるにWmi delphi code creator

UPDATE

を使用してみてください、あなたが従わなければなりません次の手順

  1. Win32_USBControllerDeviceクラスを照会します。今、あなたはディスクドライブの間のリンクを発見したことができWin32_DiskDriveToDiskPartitionクラスを使用してASSOCIATORS OF {Win32_PnPEntity.DeviceID="DeviceID"} WHERE ResultClass = Win32_DiskDrive
  2. :各dependentプロパティの抽出DeviceIDを使用して
  3. は(レコード)がそうのようなWQL文を使用してWin32_DiskDriveにloinked Win32_PnPEntityクラスをチェックするインスタンスを返さパーティション。
  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: 
+0

私は素早く見てきましたが、私はWIN_Entityを使用してデバイスを見つけることができるはずですが、私はどのようにドライブ文字に戻って関連付ける必要がありますか?私はPNPDeviceIDでこれを行うことができますか?ありがとうColin – colin

+0

非常に印象的な例のおかげで、EnumPnPEntity.Next(1、PnPEntity、iValue)= 0のかなりの遅延(約10秒)の次の行に移動する前に私のPCが行を実行するときコード、これには理由があります。 Thanks For Colin – colin

+0

'Forward Only'列挙子を追加するコードを更新するだけで、これはパフォーマンスを改善する必要があります。 – RRUZ

関連する問題