Delphi - How to get total disk space of Windows drive?
Asked Answered
C

5

5

I need to get total disk space in Delphi program.

Claret answered 17/6, 2011 at 9:6 Comment(0)
C
10

Use DiskSize and DiskFree functions for this problem. ComboBox1 contains a list of drives letters.

var
  Disk: Integer;
...
procedure TForm1.Button1Click(Sender: TObject);
var
  Total, Free: LongInt;
begin
  Total:=DiskSize(Disk) div 1024;
  Free:=DiskFree(Disk) div 1024;
  Gauge1.MaxValue:=Total;
  Gauge1.Progress:=Free;
  Label1.Caption:='Total size - '+IntToStr(Total);
  Label2.Caption:='Free - '+IntToStr(Free);
end;

procedure TForm1.ComboBox1Change(Sender: TObject);
begin
  Disk:=ComboBox1.ItemIndex+1;
end;
Chilpancingo answered 17/6, 2011 at 9:10 Comment(0)
M
5

Here you have another option using the Win32_LogicalDisk WMI class

{$APPTYPE CONSOLE}

uses
  SysUtils,
  ActiveX,
  ComObj,
  Variants;

procedure  GetWin32_LogicalDiskSize(const drive: string);
const
  WbemUser            ='';
  WbemPassword        ='';
  WbemComputer        ='localhost';
  wbemFlagForwardOnly = $00000020;
var
  FSWbemLocator : OLEVariant;
  FWMIService   : OLEVariant;
  FWbemObjectSet: OLEVariant;
  FWbemObject   : OLEVariant;
  oEnum         : IEnumvariant;
  iValue        : LongWord;
begin;
  FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
  FWMIService   := FSWbemLocator.ConnectServer(WbemComputer, 'root\CIMV2', WbemUser, WbemPassword);
  FWbemObjectSet:= FWMIService.ExecQuery(Format('SELECT * FROM Win32_LogicalDisk Where Caption=%s',[QuotedStr(drive)]),'WQL',wbemFlagForwardOnly);
  oEnum         := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
  if oEnum.Next(1, FWbemObject, iValue) = 0 then
  begin
    Writeln(Format('FreeSpace  %s Bytes',[FormatFloat('#,',FWbemObject.FreeSpace)]));// Uint64
    Writeln(Format('Size       %s Bytes',[FormatFloat('#,',FWbemObject.Size)]));// Uint64
    FWbemObject:=Unassigned;
  end;
end;


begin
 try
    CoInitialize(nil);
    try
      GetWin32_LogicalDiskSize('C:');
    finally
      CoUninitialize;
    end;
 except
    on E:Exception do
        Writeln(E.Classname, ':', E.Message);
 end;
 Writeln('Press Enter to exit');
 Readln;
end.
Metz answered 17/6, 2011 at 19:20 Comment(4)
Seems a lot more complex, although I know you are heavily into WMI. Are there any advantages over the plain Win32 based approach?Matchmark
@David The main advantage is which you can obtain the info from a remote computer as well. also using the same WMI class you can obtain more information about the disk with a single call.Metz
those comments would be beneficial to include in the answer, otherwise it looks like a laborious way to achieve the same thingMatchmark
@David, I Agree with you, now my comments explain the advantages about use the WMI approach. Also the purpose of my answer was show another way to accomplish the same task, always is good handle another alternatives to accomplish a task.Metz
A
1

Some may find this useful - it will give you total and free disk space by Volume's DeviceID. It also uses WMI like RRUZ's answer, but it works with DeviceID, so it has the same advantages + it also works with unmaped devices and drivers (or mapped to path).

procedure DiskSizesFromVolumeDeviceID(deviceID:string);
var
  WMIServices : ISWbemServices;
  Root        : ISWbemObjectSet;
  Item: Variant;
  i: Integer;
  Cap:TCap;
begin
  try
  WMIServices := CoSWbemLocator.Create.ConnectServer('.', 'root\cimv2','', '', '', '', 0,     nil);
  Root  := WMIServices.ExecQuery(Format('SELECT Capacity, FreeSpace FROM Win32_Volume     WHERE DeviceID="%s"', [StringReplace(deviceID, '\', '\\', [rfReplaceAll])]),'WQL', 0, nil);
  for i := 0 to Root.Count - 1 do
  begin
    Item := Root.ItemIndex(i);

    TotalSpace := ( Item.Capacity);
    FreeSpace := (Item.FreeSpace);
  End;
end;
Acarology answered 11/9, 2014 at 9:47 Comment(0)
P
0

Best way use this code:

var
    lpFreeBytesAvailableToCaller, 
    lpTotalNumberOfBytes, 
    lpTotalNumberOfFreeBytes : TLargeInteger; // Int64;
begin
   ...
   GetDiskFreeSpaceExA(PChar(path_to_dir), lpFreeBytesAvailableToCaller, lpTotalNumberOfBytes, @lpTotalNumberOfFreeBytes);
   ...
end;
Palindrome answered 23/8, 2023 at 6:14 Comment(0)
A
0

Just thought I'd chime in in share the solution I ended up implementing based on what I've gathered in the accepted answer:

function GetDriveCapacity(const Drive: Integer): Int64;
begin
  Result:= DiskSize(Drive);
end;

function GetDriveSpaceFree(const Drive: Integer): Int64;
begin
  Result:= DiskFree(Drive);
end;

function GetDriveSpaceUsed(const Drive: Integer): Int64;
begin
  Result:= GetDriveCapacity(Drive) - GetDriveSpaceFree(Drive);
end;

function GetDriveSpaceUsedPct(const Drive: Integer): Single;
var
  U, C: Int64;
begin
  try
    U:= GetDriveSpaceUsed(Drive);
    C:= GetDriveCapacity(Drive);
    Result:= (U / C) * 100;
  except
    Result:= -1;
  end;
end;

The core of everything here starts with GetDriveSpaceUsedPct. This returns a float between 0 and 100 representing the percentage of space available on a disk.

NOTE: Refer to the documentation for DiskSize and DiskFree when it comes to using the Drive parameter.

Usage:

procedure TForm1.TmrTimer(Sender: TObject);
var
  Perc: Double;
begin
  //C Drive Usage
  Perc:= GetDriveSpaceUsedPct(3);
  ...
  //D Drive Usage
  Perc:= GetDriveSpaceUsedPct(4);
  ...
end;
Asteria answered 15/1 at 3:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.