Delphi - 如何获取Windows驱动器的总磁盘空间?

发布于 2024-11-15 21:51:35 字数 30 浏览 1 评论 0原文

我需要获取 Delphi 程序中的总磁盘空间。

I need to get total disk space in Delphi program.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

£噩梦荏苒 2024-11-22 21:51:35

使用 DiskSize 和 DiskFree 函数解决此问题。
ComboBox1 包含驱动器盘符列表。

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;

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;
我一直都在从未离去 2024-11-22 21:51:35

在这里,您还有另一个选择,使用 Win32_LogicalDisk WMI 类

{$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.

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.
白馒头 2024-11-22 21:51:35

有些人可能会发现这很有用 - 它会根据卷的 DeviceID 为您提供总磁盘空间和可用磁盘空间。它也像 RRUZ 的答案一样使用 WMI,但它与 DeviceID 一起使用,因此它具有相同的优点+它也可以与未映射的设备和驱动程序(或映射到路径)一起使用。

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;

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;
夏日浅笑〃 2024-11-22 21:51:35

使用此代码的最佳方法:

var
    lpFreeBytesAvailableToCaller, 
    lpTotalNumberOfBytes, 
    lpTotalNumberOfFreeBytes : TLargeInteger; // Int64;
begin
   ...
   GetDiskFreeSpaceExA(PChar(path_to_dir), lpFreeBytesAvailableToCaller, lpTotalNumberOfBytes, @lpTotalNumberOfFreeBytes);
   ...
end;

Best way use this code:

var
    lpFreeBytesAvailableToCaller, 
    lpTotalNumberOfBytes, 
    lpTotalNumberOfFreeBytes : TLargeInteger; // Int64;
begin
   ...
   GetDiskFreeSpaceExA(PChar(path_to_dir), lpFreeBytesAvailableToCaller, lpTotalNumberOfBytes, @lpTotalNumberOfFreeBytes);
   ...
end;
も星光 2024-11-22 21:51:35

只是想我会根据我在接受的答案中收集的内容来分享我最终实现的解决方案:

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;

这里一切的核心都从 GetDriveSpaceUsedPct 开始。这将返回 0 到 100 之间的浮点数,表示磁盘上可用空间的百分比。

注意:在使用 Drive 参数时,请参阅有关 DiskSizeDiskFree 的文档。

用法:

procedure TForm1.TmrTimer(Sender: TObject);
var
  Perc: Double;
begin
  //C Drive Usage
  Perc:= GetDriveSpaceUsedPct(3);
  ...
  //D Drive Usage
  Perc:= GetDriveSpaceUsedPct(4);
  ...
end;

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;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文