Inno Setup get directory size including subdirectories

时间:2017-01-16 01:56:58

标签: inno-setup pascalscript

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;

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.

1 个答案:

答案 0 :(得分:1)

FindFirst确实包含子目录,但它不会为您提供尺寸。

您必须递归到子目录并按文件计算文件总大小,类似于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,您需要Unicode version of Inno Setup,无论如何都要使用{{3}}。只有当您有充分理由坚持使用Ansi版本时,才能将Int64替换为Integer,但不得限制为2 GB。