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
中处理,不需要将名称收集到列表中。
我目前被这段代码所困扰,它只让我第一次出现在我试图查找的给定目录的最顶层文件夹中的特定文件。我想将其修改为 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
中处理,不需要将名称收集到列表中。