Search code examples
delphifreepascallazarus

How to call a list of the physically attached hard disks using Free Pascal, or, failing that, Delphi?


Further to this question and this one that I asked more recently but without the correct specifics...and lastly this one that I asked at the Free Pascal forum specifically....

Can anyone provide me with guidance, examples or a link to something somewhere that explains how to call a list of the physically attached hard disks using Free Pascal, or, failing that, Delphi, regardless of whether the disks have been mounted by the operating system or not? An example is shown in the screenshot of what I am trying to achive (what is shown in this screenshot is by another software product). So pulling a list of logical volumes (C:\, E:\ etc) is not what I am trying to do. And if the disk has a filesystem that the operating system cannot mount, I still want to see the physical disk listed.

I stress that C\C++\C Sharp examples are plentifull but not what I am after. I need primarily Free Pascal example, or, failing that, Delphi.

enter image description here


Solution

  • Try the Win32_DiskDrive WMI class, check this sample code

    {$mode objfpc}{$H+}
    uses
      SysUtils,ActiveX,ComObj,Variants;
    {$R *.res}
    
    // The Win32_DiskDrive class represents a physical disk drive as seen by a computer running the Win32 operating system. Any interface to a Win32 physical disk drive is a descendent (or member) of this class. The features of the disk drive seen through this object correspond to the logical and management characteristics of the drive. In some cases, this may not reflect the actual physical characteristics of the device. Any object based on another logical device would not be a member of this class.
    // Example: IDE Fixed Disk.
    
    procedure  GetWin32_DiskDriveInfo;
    const
      WbemUser            ='';
      WbemPassword        ='';
      WbemComputer        ='localhost';
      wbemFlagForwardOnly = $00000020;
    var
      FSWbemLocator : OLEVariant;
      FWMIService   : OLEVariant;
      FWbemObjectSet: OLEVariant;
      FWbemObject   : Variant;
      oEnum         : IEnumvariant;
      sValue        : string;
    begin;
      FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
      FWMIService   := FSWbemLocator.ConnectServer(WbemComputer, 'root\CIMV2', WbemUser, WbemPassword);
      FWbemObjectSet:= FWMIService.ExecQuery('SELECT * FROM Win32_DiskDrive','WQL',wbemFlagForwardOnly);
      oEnum         := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
      while oEnum.Next(1, FWbemObject, nil) = 0 do
      begin
        sValue:= FWbemObject.Properties_.Item('Caption').Value;
        Writeln(Format('Caption        %s',[sValue]));// String
        sValue:= FWbemObject.Properties_.Item('DeviceID').Value;
        Writeln(Format('DeviceID       %s',[sValue]));// String
        sValue:= FWbemObject.Properties_.Item('Model').Value;
        Writeln(Format('Model          %s',[sValue]));// String
        sValue:= FWbemObject.Properties_.Item('Partitions').Value;
        Writeln(Format('Partitions     %s',[sValue]));// Uint32
        sValue:= FWbemObject.Properties_.Item('PNPDeviceID').Value;
        Writeln(Format('PNPDeviceID    %s',[sValue]));// String
        sValue:= FormatFloat('#,', FWbemObject.Properties_.Item('Size').Value / (1024*1024));
        Writeln(Format('Size           %s mb',[sValue]));// Uint64
    
        Writeln;
        FWbemObject:= Unassigned;
      end;
    end;
    
    begin
      try
        GetWin32_DiskDriveInfo;
      except
        on E:EOleException do
            Writeln(Format('EOleException %s %x', [E.Message,E.ErrorCode]));
        on E:Exception do
            Writeln(E.Classname, ':', E.Message);
      end;
      Writeln('Press Enter to exit');
      Readln;
    end.    
    

    After of running this code you will get a output like this

    enter image description here