Inno Setup: Как мне рекурсивно перечислить все каталоги по заданному пути, который включает указанный файл c (в данном случае '240. json')? - PullRequest
2 голосов
/ 23 января 2020

В настоящее время я застрял с этим битом кода, который дает мне только самое первое вхождение указанного c файла в самой верхней папке данного каталога, которую я пытаюсь найти. Я хочу изменить это, чтобы перечислить / вернуть все вхождения файла.

{ 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;

1 Ответ

1 голос
/ 23 января 2020

Следующий код собирает все найденные файлы в 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, и вам не нужно собирать имена в список.

...