代码之家  ›  专栏  ›  技术社区  ›  Jose Eduardo

如何使用WMI和Delphi关联逻辑驱动器和物理磁盘?

  •  4
  • Jose Eduardo  · 技术社区  · 13 年前

    我已经花了很长时间研究一个可以从Micro读取信息的应用程序,有些(大多数)失败了,还有一些仍然缺失,我正在使用WMI和Delphi。 我面临的问题是,我需要列出属于每个HD的单元,例如:HD1有驱动器C:,D:等等。

    非常感谢。

    2 回复  |  直到 13 年前
        1
  •  12
  •   RRUZ    13 年前

    要关联逻辑驱动器和物理磁盘,必须使用 Win32_DiskDrive 类和 Win32_DiskDriveToDiskPartition , Win32_LogicalDiskToPartition ASSOCIATORS 类。

    试试这个例子。

    {$APPTYPE CONSOLE}
    
    uses
      SysUtils,
      ActiveX,
      ComObj,
      Variants;
    
    
    function ListDrives : string;
    var
      FSWbemLocator  : OLEVariant;
      objWMIService  : OLEVariant;
      colDiskDrives  : OLEVariant;
      colLogicalDisks: OLEVariant;
      colPartitions  : OLEVariant;
      objdiskDrive   : OLEVariant;
      objPartition   : OLEVariant;
      objLogicalDisk : OLEVariant;
      oEnumDiskDrive : IEnumvariant;
      oEnumPartition : IEnumvariant;
      oEnumLogical   : IEnumvariant;
      iValue         : LongWord;
      DeviceID       : string;
    begin;
      Result:='';
      FSWbemLocator   := CreateOleObject('WbemScripting.SWbemLocator');
      objWMIService   := FSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', '');
      colDiskDrives   := objWMIService.ExecQuery('SELECT DeviceID FROM Win32_DiskDrive');
      oEnumDiskDrive  := IUnknown(colDiskDrives._NewEnum) as IEnumVariant;
      while oEnumDiskDrive.Next(1, objdiskDrive, iValue) = 0 do
       begin
          Writeln(Format('DeviceID %s',[string(objdiskDrive.DeviceID)]));
          //Escape the `\` chars in the DeviceID value because the '\' is a reserved character in WMI.
          DeviceID        := StringReplace(objdiskDrive.DeviceID,'\','\\',[rfReplaceAll]); 
          //link the Win32_DiskDrive class with the Win32_DiskDriveToDiskPartition class
          colPartitions   := objWMIService.ExecQuery(Format('ASSOCIATORS OF {Win32_DiskDrive.DeviceID="%s"} WHERE AssocClass = Win32_DiskDriveToDiskPartition',[DeviceID]));
          oEnumPartition  := IUnknown(colPartitions._NewEnum) as IEnumVariant;
          while oEnumPartition.Next(1, objPartition, iValue) = 0 do
          begin
           if not VarIsNull(objPartition.DeviceID) then
           begin
            Writeln(Format('   Partition %s',[string(objPartition.DeviceID)]));
            //link the Win32_DiskPartition class with theWin32_LogicalDiskToPartition class.
            colLogicalDisks := objWMIService.ExecQuery('ASSOCIATORS OF {Win32_DiskPartition.DeviceID="'+VarToStr(objPartition.DeviceID)+'"} WHERE AssocClass = Win32_LogicalDiskToPartition'); 
            oEnumLogical  := IUnknown(colLogicalDisks._NewEnum) as IEnumVariant;
              while oEnumLogical.Next(1, objLogicalDisk, iValue) = 0 do
              begin
                  Writeln(Format('     Logical Disk %s',[string(objLogicalDisk.DeviceID)]));
                  objLogicalDisk:=Unassigned;
              end;
           end;
           objPartition:=Unassigned;
          end;
           objdiskDrive:=Unassigned;
       end;
    end;
    
    begin
     try
        CoInitialize(nil);
        try
          ListDrives;
        finally
          CoUninitialize;
        end;
     except
        on E:Exception do
            Writeln(E.Classname, ':', E.Message);
      end;
      Readln;
    end.
    

    这将输出类似的内容

    DeviceID \\.\PHYSICALDRIVE0
       Partition Disk #0, Partition #0
         Logical Disk F:
    DeviceID \\.\PHYSICALDRIVE1
       Partition Disk #1, Partition #0
         Logical Disk C:
    
        2
  •  2
  •   Arioch 'The    13 年前

    使用MagWMi包装器及其一行函数(一行很慢,但这不是需要速度的地方)。 我用它来制作二级磁盘列表。

    • 硬盘驱动器1->字母1、字母2
    • 硬盘驱动器2->字母3、字母4
    • 网络服务器1->字母5、字母6
    • 网络服务器2->字母7、字母8
    • 无法识别->所有其他字母

    但你必须记住,有些磁盘可能没有任何字母。 所以这会告诉你有关根目录的信息,但不会更多。 磁盘C:可能派生为多个物理磁盘。 有些物理磁盘可能根本没有字母。

    unit WMI_Helper;
    
    interface
    
    function WMINetDiskName(const disk: string { 'C:' - w/o slash } ): string;
    function WMIPhysDiskName(const disk: string { 'C:' - w/o slash } ): string;
    function WMIGetVolumeName(const disk: string { 'C:' - w/o slash } ): string;
    
    implementation
    
    uses magwmi, SysUtils, StrUtils, Windows, IOUtils;
    
    function WMIGetProp(const query, param, resultProp: string): string;
    begin
      if MagWmiGetOneQ(StringReplace(query, '%s', param, []), resultProp, Result) <= 0
      then
        Result := '';
      Result := Trim(Result);
    end;
    
    function WMINetDiskName(const disk: string { 'C:' - w/o slash } ): string;
    const
      req = 'select ProviderName from Win32_MappedLogicalDisk where DeviceID = "%s"';
      prop = 'ProviderName';
    var
      i: integer;
    begin
      Result := WMIGetProp(req, disk, prop);
    
      If not TPath.IsUNCPath(Result) then
        exit('');
    
      i := PosEx('\', TPath.GetPathRoot(Result), 3);
      if i <= 0 then
        exit('');
    
      SetLength(Result, i - 1);
    end;
    
    function WMIPhysDiskName(const disk: string { 'C:' - w/o slash } ): string;
    const
      resultProp = 'DeviceID';
      reqPart = 'ASSOCIATORS OF {Win32_LogicalDisk.DeviceID="%s"} WHERE ResultClass=Win32_DiskPartition';
      reqDisk = 'ASSOCIATORS OF {Win32_DiskPartition.DeviceID="%s"} WHERE ResultClass=Win32_DiskDrive';
    begin
      Result := WMIGetProp(reqPart, disk, resultProp);
      if Result > '' then
        Result := WMIGetProp(reqDisk, Result, resultProp);
    end;
    
    function WMIGetVolumeName(const disk: string { 'C:' - w/o slash } ): string;
    const
      prop = 'VolumeName';
      reqNet = 'select VolumeName from Win32_MappedLogicalDisk where DeviceID = "%s"';
      reqPhy = 'select VolumeName from Win32_LogicalDisk where DeviceID = "%s"';
    
    begin
      Result := WMIGetProp(IfThen(GetDriveType(PChar(disk)) = DRIVE_REMOTE, reqNet,
        reqPhy), disk, prop);
    end;
    
    end.
    
    推荐文章