4

私はすでに Micro から情報を読み取ることができるアプリケーションに長い間取り組んできましたが、いくつかの (ほとんどの) 失敗したものはまだいくつか欠けています。私は WMI と Delphi を使用しています。私が直面している問題は、各 HD に属するユニットをリストする必要があることです。たとえば、HD1 にはドライブ C:、D: などがあります。

ありがとうございました

4

2 に答える 2

12

Win32_DiskDrive論理ドライブと物理ディスクを相互に関連付けるには、クラスとWin32_DiskDriveToDiskPartitionASSOCIATORSクラスを使用する必要があります。Win32_LogicalDiskToPartition

このサンプルを試してください。

{$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:
于 2012-09-04T21:45:11.443 に答える
2

MagWMi ラッパーとそのワンライナー関数を使用します (ワンライナーは遅いですが、速度が必要な場所ではありません)。これを使用して、2 レベルのディスク リストを作成しました。

  • ハードドライブ 1 -> レター 1、レター 2
  • ハードドライブ 2 -> レター 3、レター 4
  • NetServer 1 -> レター 5、レター 6
  • NetServer 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.
于 2012-09-05T09:35:36.847 に答える