Inno Setup获取包括子目录在内的目录大小
我正在尝试编写一个返回目录大小的函数.我已经编写了以下代码,但是没有返回正确的大小.例如,当我在{pf}
目录上运行它时,它返回174个字节,这显然是错误的,因为此目录的大小为数GB.这是我的代码:
I am trying to write a function that returns the size of a directory. I have written the following code, but it is not returning the correct size. For example, when I run it on the {pf}
directory it returns 174 bytes, which is clearly wrong as this directory is multiple Gigabytes in size. Here is the code I have:
function GetDirSize(DirName: String): Int64;
var
FindRec: TFindRec;
begin
if FindFirst(DirName + '\*', FindRec) then
begin
try
repeat
Result := Result + (Int64(FindRec.SizeHigh) shl 32 + FindRec.SizeLow);
until not FindNext(FindRec);
finally
FindClose(FindRec);
end;
end
else
begin
Result := -1;
end;
end;
我怀疑FindFirst
函数不包含子目录,这就是为什么我没有得到正确的结果.因此,如何返回目录的正确大小,即包括所有子目录中的所有文件,与在Windows资源管理器中选择``文件夹上的属性''相同?我正在使用FindFirst
,因为该功能需要支持超过2GB的目录大小.
I suspect that the FindFirst
function does not include subdirectories, which is why I am not getting the correct result. Therefore, how can I return the correct size of a directory i.e. including all files in all subdirectories, the same as selecting Properties on a Folder in Windows Explorer? I am using FindFirst
as the function needs to support directory sizes over 2GB.
FindFirst
确实包含子目录,但无法获取它们的大小.
The FindFirst
does include subdirectories, but it won't get you their sizes.
您必须递归到子目录并逐个文件计算总大小,例如类似于 Inno Setup:复制文件夹,子文件夹和文件在代码"部分递归.
You have to recurse into subdirectories and calculate the total size file by file, similarly as to for example Inno Setup: copy folder, subfolders and files recursively in Code section.
function GetDirSize(Path: String): Int64;
var
FindRec: TFindRec;
FilePath: string;
Size: Int64;
begin
if FindFirst(Path + '\*', FindRec) then
begin
Result := 0;
try
repeat
if (FindRec.Name <> '.') and (FindRec.Name <> '..') then
begin
FilePath := Path + '\' + FindRec.Name;
if (FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY) <> 0 then
begin
Size := GetDirSize(FilePath);
end
else
begin
Size := Int64(FindRec.SizeHigh) shl 32 + FindRec.SizeLow;
end;
Result := Result + Size;
end;
until not FindNext(FindRec);
finally
FindClose(FindRec);
end;
end
else
begin
Log(Format('Failed to list %s', [Path]));
Result := -1;
end;
end;
对于Int64
,您需要 Inno Setup的Unicode版本,无论如何都应使用.仅当您非常有理由坚持使用Ansi版本时,才可以将Int64
替换为Integer
,但是限制为2 GB.
For Int64
, you need Unicode version of Inno Setup, what you should be using in any case. Only if you have a very good reason to stick with Ansi version, you can replace the Int64
with Integer
, but than you are limited to 2 GB.