greetings from Iceland!
To begin with, I have searched both with google and here with no result.
I'm writing in Delphi and have couple of years experience in Delphi (over 30 years in Pascal)
I have build over these years variety of files utility's programs and used the functions FindFirst and FindNext in almost every such app. Today I was using a old file-utility program I wrote and found out it didn't work 100%
It was ok until the directory name got somehow strange, i.e. name with couple of periods inside. The story is I was installing Wamp and some folders there was named with this strange method.
As: "c:\wamp\apps\phpmyadmin3.4.5"
"c:\wamp\apps\sqlbuddy1.3.3"
"c:\wamp\apps\webgrind1.0 etc"
When I did debugging, I found out Findnext just returned error 18 which is same error as FindNext return when no more files is to find.
I have tried FindFirstFile and FindNextFile with same result. I'm thinking to try API FindNextFileEx, if this has to do with long file names, but not so optimistic..
Also I notice the attribute in these folders wasn't 16 (hex10) instead it was 8208 (8192+16), but it doesn't have anything to do with this problem as I could for example mask (AND) the attr with $00FF etc.
PROCEDURE TForm_Leit.Finna_Dir (Str_InnDir : STRING);
VAR
S_Rec1 : TSearchRec;
Bo_Buid : BOOLEAN;
BEGIN
.
.
.
//Find Dir part
IF (FindFirst (Str_Inndir+'\*.', faDirectory, S_Rec1) = 0) THEN
REPEAT
Bo_Buid := FALSE;
IF ((S_Rec1.Name = '.') OR (S_Rec1.Name = '..')) THEN
REPEAT
Bo_Buid := FindNext (S_Rec1) <> 0;
UNTIL NOT((S_Rec1.Name = '.') OR (S_Rec1.Name = '..')) OR (Bo_BUid);
IF NOT(Bo_Buid) THEN
Finna_Dir (Str_Inndir+'\'+S_Rec1.Name); //Recursion
UNTIL (FindNext (S_Rec1) <> 0);
END;
The pattern you're using ('\*.'
) only matches with file and directory names without a period in it (which also means no extension for files). Try with:
IF (FindFirst (Str_Inndir+'\*', ...
To eloborate a little, VCL's 'Find..' functions are wrappers around the underlying API's 'Find..' functions which does not really care if you want to search for files or folders (the 'Attr' parameter you can pass to sysutils.FindFirst
is a facility provided by VCL, and the VCL can only effect the search outcome by filtering it). So the result of using a '*.
' pattern will not be different for a file or a folder. If the pattern cannot return a file name with a period in it, then it also cannot return a folder with a period in it.
The usage of the parameter is the same with the dir
command. Navigate to your '..\apps' folder from a command prompt, and if you issue a >dir *.
you won't see the folders in your question listed.
You can have a look at and try with different 'Pattern's in the following sample code ,which only uses the API to enumerate files, to see how different wild cards effect the search outcome.
var
Data: TWIN32FindData;
procedure ListFiles(const Path, Pattern: string; List: TStrings);
function IsDot: Boolean;
begin
Result := (string(Data.cFileName) = '.') or (Data.cFileName = '..');
end;
function IsDirectory: Boolean;
begin
Result := Bool(Data.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY);
end;
procedure PutFileName;
begin
if not IsDot then begin
if IsDirectory then
List.Add(Path + '\' + Data.cFileName + ' <dir>')
else
List.Add(Path + '\' + Data.cFileName); //'
end;
end;
var
FindHandle: THandle;
begin
FindHandle := FindFirstFile(PChar(Path + Pattern), Data);
if FindHandle <> INVALID_HANDLE_VALUE then
try
PutFileName;
while FindNextFile(FindHandle, Data) do begin
PutFileName;
if (not IsDot) and IsDirectory then
ListFiles(Path + '\' + Data.cFileName, Pattern, List); //'
end;
finally
windows.FindClose(FindHandle);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
const
Pattern = '\*';
begin
Memo1.Clear;
ListFiles('..sometestdirectory..', Pattern, Memo1.Lines);
end;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With