Inno Setup:如何递归列出给定路径中包含特定文件(在本例中为“240.json”)的所有目录?

Inno Setup: How do I recursively list all directories in a given path that includes a specific file (in this case, '240.json')?

我目前被这段代码所困扰,它只让我第一次出现在我试图查找的给定目录的最顶层文件夹中的特定文件。我想将其修改为 list/return 文件的所有匹配项。

{ Credits to (I believe) TLama for some/most of this excerpt of code. }

{ Looks for specific file }
var
  filelocation: string;
  { ^ Global Variable }

function FindFile(RootPath: string; FileName: string): string;
var
  FindRec: TFindRec;
  FilePath: string;
begin
  Log(Format('', [RootPath, FileName]));

  if FindFirst(RootPath + '\*', FindRec) then
  begin
    try
      repeat
        if (FindRec.Name <> '.') and (FindRec.Name <> '..') then
        begin
          FilePath := RootPath + '\' + FindRec.Name;
          if FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY <> 0 then
          begin
            Log(FilePath);
            Result := FindFile(FilePath, FileName);
            if Result <> '' then Exit;
          end
            else
          if CompareText(FindRec.Name, FileName) = 0 then
          begin 
            { list each \userdata\(numbers here) here that include 240.json within them }
            Log(Format('User' + {user} + ' owns (Game Here) on Steam.', [FilePath]));

            Result := FilePath;
            filelocation := FilePath
          end;                             
        end;
      until not FindNext(FindRec);
    finally
      FindClose(FindRec);
    end;
  end
    else
  begin
    Log(Format('Failed to list %s', [RootPath]));
    MsgBox('You do not own (Game Here). Please purchase and install it from Steam.',
           mbError, MB_OK);
    Exit;
  end;
end;

以下代码将所有找到的文件收集到 TStringList:

procedure FindFile(RootPath: string; FileName: string; FileLocations: TStringList);
var
  FindRec: TFindRec;
  FilePath: string;
begin
  Log(Format('Looking for %s in %s', [FileName, RootPath]));

  if FindFirst(RootPath + '\*', FindRec) then
  begin
    try
      repeat
        if (FindRec.Name <> '.') and (FindRec.Name <> '..') then
        begin
          FilePath := RootPath + '\' + FindRec.Name;
          if FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY <> 0 then
          begin
            FindFile(FilePath, FileName, FileLocations);
          end
            else
          if CompareText(FindRec.Name, FileName) = 0 then
          begin 
            Log(Format('Found %s', [FilePath]));

            { Here you can do additional check (for file contents) }

            FileLocations.Add(FilePath);

            Break;
          end;                             
        end;
      until not FindNext(FindRec);
    finally
      FindClose(FindRec);
    end;
  end
    else
  begin
    Log(Format('Failed to list %s', [RootPath]));
  end;
end;

您可以像这样使用它:

var
  FileLocations: TStringList;
begin
  FileLocations := TStringList.Create();
  FindFile('C:\some\path', '240.json', FileLocations);
end;

然后根据需要处理 FileLocations

for I := 0 to FileLocations.Count - 1 do
begin
  FileName := FileLocations[I];
  { Process FileName }
end;

虽然如果不需要多次处理文件,也可以直接在FindFile中处理,不需要将名称收集到列表中。