2010-02-27 140 views
4

背景
我一直在使用Win32_DiskDrive找到閃存(USB筆,SD卡等)進行區分,但在其他計算機上進行了一些測試後,我注意到它們並不總是被發現。所以我使用的是Win32_LogicalDisk,因爲它具有DriveType,所以我不必關聯兩個類(例如分區)來首先找到驅動器,然後找到它們的驅動器盤符。WMI:如何將內部的「本地磁盤」 HDD和外部「本地磁盤」 HDD

問題是在LogicalDisk中檢測到外部硬盤驅動器爲DriveType 3(本地磁盤),DiskDrive中的功能中沒有7(支持可移動介質)。所以我無法區分內部驅動和外部驅動。

問題
我怎麼知道內部使用邏輯磁盤的外部硬盤之間的差額(或盤驅動,如果你真的有)什麼的第三位。

好的。這個問題已經回答了!
下面是代碼,如果有人感興趣。

program GetWMI_USBConnectedInfo; 

{$APPTYPE CONSOLE} 

uses 
    Windows, 
    Classes, 
    ActiveX, 
    Variants, 
    SysUtils, 
    WbemScripting_TLB, // Using the .pas supplied by the wrapper as it seems to be the XP version of 1.2 
    magwmi, 
    magsubs1; 

function CheckType(Str: string): boolean; 
var 
    I: Integer; 
    Str2: string; 
begin 
    Result := False; 
    for I := 1 to Length(Str) - 1 do if Str[I] = '\' then begin 
    Str2 := Copy(Str, 1, I-1); 
    Str2 := LowerCase(Str2); 
    if (Str2 = 'usbstor') or (Str2 = 'flashmedia') then 
     Result := True; 
    Break; 
    end; 
end; 

procedure GetUSBDiskDriveInfo; 
var 
    I, II, III: Integer; 
    Start, Stop, Freq: Int64; 
    instances, instances2, instances3: integer ; 
    WmiResults, WmiResults2, WmiResults3: T2DimStrArray ; 
    errstr: string ; 
begin 
    QueryPerformanceFrequency(Freq); 
    QueryPerformanceCounter(Start); 
    try 
    MagWmiGetInfoEx('.', 'root\CIMV2', '', '', 'SELECT * FROM Win32_DiskDrive', WmiResults, instances, errstr); 
    for I := 1 to instances do begin 
     MagWmiGetInfoEx('.', 'root\CIMV2', '', '', 'ASSOCIATORS OF {Win32_DiskDrive.DeviceID=''' + WmiResults[I, 12] + '''} WHERE AssocClass = Win32_DiskDriveToDiskPartition', WmiResults2, instances2, errstr); 
     for II := 1 to instances2 do begin 
     MagWmiGetInfoEx('.', 'root\CIMV2', '', '', 'ASSOCIATORS OF {Win32_DiskPartition.DeviceID=''' + WmiResults2[II, 11] + '''} WHERE AssocClass = Win32_LogicalDiskToPartition', WmiResults3, instances3, errstr); 
     for III := 1 to instances3 do begin 
      if CheckType(WmiResults[I, 32]) or (Pos('7', WmiResults[I, 3])>0) then begin 
      Write(WmiResults3[III, 4]); 
      Write(WmiResults3[III, 39]); 
      Writeln; 
      end; 
     end; 
     WmiResults3 := nil; 
     end; 
     WmiResults2 := nil; 
    end; 
    WmiResults := nil; 
    except 
    Writeln; 
    Writeln('error: '+errstr); 
    end; 
    Writeln; 
    QueryPerformanceCounter(Stop); 
    if (Freq > 0) then 
    Writeln('It took ' + FormatFloat('0.#0', (Stop-Start)/Freq) + ' seconds to complete.'); 
end; 

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

還有一件事!
稱這是一個骯髒的黑客或什麼,但我爲了註釋掉MagWmiGetInfoEx(在magwmi線298)的這一部分,使其工作:

//  if Pos ('SELECT', Arg) = 1 then 
      wmiObjectSet := wmiServices.ExecQuery (Arg, 'WQL', wbemFlagReturnImmediately, nil) 
//  else 
//   wmiObjectSet := wmiServices.InstancesOf (Arg, wbemFlagReturnImmediately or 
//                wbemQueryFlagShallow, nil) 
; 
+0

哦,這個代碼不僅僅是尋找外部硬盤。它還會檢測USB筆和閃存卡。 – 2010-03-01 20:49:26

+0

我的第一個問題已被刪除,因爲我不需要它(DBT_DEVICEARRIVAL和DBT_DEVICEREMOVECOMPLETE已經完成了這項工作)。 – 2010-03-01 21:08:22

回答

4

我會建議使用WMI堅持。有一個很好的delphi wrapper可用,其中包括完整的來源,讓你開始。

開始的查詢是「SELECT * FROM WIN32_DiskDrive」,它將返回系統中所有磁盤驅動器的所有信息。對於任何USB驅動器,PNPDeviceID字段應以USBSTOR開頭。 MSDN網站是什麼領域回來的良好資源。只需將對象轉換爲查詢即可。

如果您打算從線程調用此函數,您可能需要在進行任何調用之前添加初始化COM(ComInitialize)。在銷燬您的線程之前,請調用ComUnitialialize。

1

你可以測試這個包; SourceForge中的GLibWMI Components Library。這是與WMI合作的包裝。包含CDiskDriveInfo,CDiskPartitionInfo,CUSBControllerInfo等組件,可以幫助您。

此外所有代碼都包含在內。你可以評估它。

問候。