2010-02-27 110 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等组件,可以帮助您。

此外所有代码都包含在内。你可以评估它。

问候。

相关问题