Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

delphi - How can I get the drive letter of an USB device?

I am using WMI to get all inserted USB disks manufactures names. The code works great but I have a problem how can I determine witch drive letter a certain disk has... I can get only the device name e.g

(\.PhysicalDrive1) ... how can I translate this in a normal drive letter?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

If you are getting values like \.PHYSICALDRIVE1 means which you are using the Win32_DiskDrive wmi class and the DeviceID Property , so in order to get the Drive letter you must use an ASSOCIATORS class, which will create a link between the wmi classes with contain the information which you are looking for (Win32_LogicalDisk) and the class which you are using (Win32_DiskDrive).

So you must do something like this

Win32_DiskDrive-> Win32_DiskDriveToDiskPartition -> Win32_DiskPartition -> Win32_LogicalDiskToPartition -> Win32_LogicalDisk

Check this sample function

{$APPTYPE CONSOLE}

uses
  SysUtils,
  ActiveX,
  ComObj,
  Variants;


function DeviceIDToDrive(const ADeviceID : string) : string;
var
  FSWbemLocator  : OLEVariant;
  objWMIService  : OLEVariant;
  colLogicalDisks: OLEVariant;
  colPartitions  : OLEVariant;
  objPartition   : OLEVariant;
  objLogicalDisk : OLEVariant;
  oEnumPartition : IEnumvariant;
  oEnumLogical   : IEnumvariant;
  iValue         : LongWord;
  DeviceID       : string;
begin;
  Result:='';
  FSWbemLocator   := CreateOleObject('WbemScripting.SWbemLocator');
  objWMIService   := FSWbemLocator.ConnectServer('localhost', 'rootCIMV2', '', '');
  DeviceID        := StringReplace(ADeviceID,'','\',[rfReplaceAll]); //Escape the `` chars in the DeviceID value because the '' is a reserved character in WMI.
  colPartitions   := objWMIService.ExecQuery(Format('ASSOCIATORS OF {Win32_DiskDrive.DeviceID="%s"} WHERE AssocClass = Win32_DiskDriveToDiskPartition',[DeviceID]));//link the Win32_DiskDrive class with the Win32_DiskDriveToDiskPartition class
  oEnumPartition  := IUnknown(colPartitions._NewEnum) as IEnumVariant;
  while oEnumPartition.Next(1, objPartition, iValue) = 0 do
   begin
       if not VarIsNull(objPartition.DeviceID) then
       begin
        colLogicalDisks := objWMIService.ExecQuery('ASSOCIATORS OF {Win32_DiskPartition.DeviceID="'+VarToStr(objPartition.DeviceID)+'"} WHERE AssocClass = Win32_LogicalDiskToPartition'); //link the Win32_DiskPartition class with theWin32_LogicalDiskToPartition class.
        oEnumLogical  := IUnknown(colLogicalDisks._NewEnum) as IEnumVariant;
          if oEnumLogical.Next(1, objLogicalDisk, iValue) = 0 then
          begin
              Result:=objLogicalDisk.DeviceID;
              objLogicalDisk:=Unassigned;
          end;
       end;
       objPartition:=Unassigned;
   end;
end;

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...