Gnom_aka_Lexander,
El Sanchez,
дельфи и инно используют для поиска WinApi функции:
function FindFirstFile(...): THandle;
function FindNextFile(...): BOOL;
function FindClose(...): BOOL;
которые лежат в kernel32.dll и работа напрямую с этими функциями дала бы некоторое повышение скорости
а то получаем торомоза из-за вызова функции внутри другой
вот накатал 2 примера рекурсивного поиска по расширению: обычная и с использованием вышеупомянутых WinApi напрямую:
читать дальше »
Код:

[Setup]
AppName=My Program
AppVerName=My Program v.1.2
DefaultDirName={pf}\My Program
CreateAppDir=no
DisableWelcomePage=yes
InfoBeforeFile=compiler:Default.isl
[code]
#ifdef UNICODE
#define A "W"
#else
#define A "A"
#endif
const
MAX_PATH = 260;
INVALID_HANDLE_VALUE = -1;
type
_WIN32_FIND_DATA = record
dwFileAttributes: DWORD;
ftCreationTime: TFileTime;
ftLastAccessTime: TFileTime;
ftLastWriteTime: TFileTime;
nFileSizeHigh: DWORD;
nFileSizeLow: DWORD;
dwReserved0: DWORD;
dwReserved1: DWORD;
cFileName: array[0..MAX_PATH - 1] of Char;
cAlternateFileName: array[0..13] of Char;
end;
function FindFirstFile(lpFileName: String; var lpFindFileData: _WIN32_FIND_DATA): THandle; external 'FindFirstFile{#A}@kernel32.dll stdcall';
function FindNextFile(hFindFile: THandle; var lpFindFileData: _WIN32_FIND_DATA): BOOL; external 'FindNextFile{#A}@kernel32.dll stdcall';
function Win_Api_FindClose(hFindFile: THandle): BOOL; external 'FindClose@kernel32.dll stdcall';
function GetTickCount(): DWORD; external 'GetTickCount@kernel32.dll stdcall';
function CharArrayToString(cArray: array of Char): String;
begin
Result := '';
while cArray[Length(Result)] <> #0 do Insert(cArray[Length(Result)], Result, Length(Result)+1);
end;
function WinApiSearchForFiles(const RootFolder, Extension: String; var ResultPathArray: array of String): Boolean; // get all files with their path
var
FindData: _WIN32_FIND_DATA;
NewSearchPath: String;
hFindFile: THandle;
Len: Integer;
begin
NewSearchPath := AddBackslash(RemoveBackslash(RootFolder));
hFindFile := FindFirstFile(NewSearchPath + Extension, FindData);
if hFindFile = INVALID_HANDLE_VALUE then
begin
MsgBoxEx(0, SysErrorMessage(DLLGetLastError), SetupMessage(msgErrorTitle), MB_OK, 0, 0);
Exit;
end;
try
repeat
if FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY = 0 then
begin
Len := GetArrayLength(ResultPathArray);
SetArrayLength(ResultPathArray, Len+1);
ResultPathArray[Len] := NewSearchPath + CharArrayToString(FindData.cFileName);
end else if (FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY = FILE_ATTRIBUTE_DIRECTORY) and (String(FindData.cFileName[0]) <> '.') and (String(FindData.cFileName[0]) <> '..') then
/// recurse
WinApiSearchForFiles(AddBackslash(NewSearchPath + CharArrayToString(FindData.cFileName)), Extension, ResultPathArray);
until not FindNextFile(hFindFile, FindData);
finally
Result := Win_Api_FindClose(hFindFile);
end;
end;
////////////////////////////////////////////////////////////////
procedure SearchForFiles(const RootFolder, Extension: String; var ResultPathArray: array of String); // get all files with their path
var
NewSearchPath: String;
FindRec: TFindRec;
Len: Integer;
begin
NewSearchPath := AddBackslash(RemoveBackslash(RootFolder));
if FindFirst(NewSearchPath + Extension, FindRec) then
try
repeat
if (FindRec.Name <> '.') and (FindRec.Name <> '..') then
begin
if FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY = 0 then
begin
Len := GetArrayLength(ResultPathArray);
SetArrayLength(ResultPathArray, Len+1);
ResultPathArray[Len] := NewSearchPath + FindRec.Name;
end else
if FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY = FILE_ATTRIBUTE_DIRECTORY then SearchForFiles(NewSearchPath + FindRec.Name, Extension, ResultPathArray);
end;
until not FindNext(FindRec);
finally
FindClose(FindRec);
end;
end;
procedure InitializeWizard;
var
i: Integer;
S: String;
UndefArray: array of String;
dwStartTime: DWORD;
begin
// dwStartTime := GetTickCount();
// SearchForFiles('C:\Program Files\Adobe\Adobe Photoshop CS5.1 (64 Bit)', '*.*', UndefArray);
// MsgBox('Inno Search Time:' + #32 + IntToStr(GetTickCount()-dwStartTime), mbInformation, MB_OK);
dwStartTime := GetTickCount();
WinApiSearchForFiles('C:\Program Files\Adobe\Adobe Photoshop CS5.1 (64 Bit)', '*.*', UndefArray);
MsgBox('Win Api Search Time:' + #32 + IntToStr(GetTickCount()-dwStartTime), mbInformation, MB_OK);
for i := 0 to GetArrayLength(UndefArray)-1 do S := S + #13#10 + UndefArray[i];
WizardForm.InfoBeforeMemo.Text := S;
end;
но в результате обычная работает быстрее тк, для апишной приходится использовать функцию конвертации массива символов в строку, тк урезанная инно не умеет преобразовать тип String(array of Char)
=================
ускорить поиск думаю можно указанием имени файла а не расширения:
SearchForFiles('C:\Program Files\Adobe\Adobe Photoshop CS5.1 (64 Bit)',
'Bib.dll', UndefArray);