-2

I'm having trouble writing code for a procedure that will open a directory folder and delete all of the files within it recursively so that I can in turn delete the folder itself. I won't have trouble with the recursive procedure, but I can't seem to get the FindFirst/FindNext/FindClose functions to work properly. The procedure below should search the current directory for any files of any type (however I may be misusing string wildcards; I didn't find much online about the syntax of their use).

procedure TForm1.Button1Click(Sender: TObject);
var SR: TSearchRec;
begin
 ShowMessage(GetCurrentDir);
 if (FindFirst('\*.*',faAnyFile,SR)=0) then
 begin
  repeat
   ShowMessage(SR.Name);
  until FindNext(SR)<>0;
  FindClose(SR);
 end
 else begin
  ShowMessage('No matching files found');
 end;
end;

Right now it seems that no matter what I put in for the filename, the procedure never finds any files and always returns the 'No matching files found' message.

Rob Kennedy
  • 161,384
  • 21
  • 275
  • 467
  • Have you tried to be explicit about the path in your call to `FindFirst`? Also, you do know that the 'current' directory can be anything, so you are about to permanently delete a random directory on your user's system? – Andreas Rejbrand Jul 15 '13 at 14:07
  • @AndreasRejbrand - In the real code that I'm using, I have the current directory defined right above this using the SetCurrentDir function, but I omitted that because it's pretty lengthy and not necessary for my problem. I have the Current Directory displayed in a message at the start of the procedure so that I can see what directory I'm working in. And yes, I have tried being explicit. I've even put in a string for a specific file that I'm looking for (i.e. 'C:\Program Files\Test.txt') –  Jul 15 '13 at 14:20
  • It is still possible that the [`FindFirstFile` API function](http://msdn.microsoft.com/en-us/library/windows/desktop/aa364418(v=vs.85).aspx) doesn't work unless given a fully-qualified path. Maybe it doesn't care about the current working directory? In any case, have you tried simply to replace `\*.*` by `*.*`? – Andreas Rejbrand Jul 15 '13 at 14:22
  • Yeah, I've tried several different iterations of string wildcards, as well as just spelling out specific files. –  Jul 15 '13 at 14:26
  • But there are no other errors in your code... :( Try it in a new, empty, VCL or command-line project, and hard-code the path `C:\WINDOWS\*.*` (or whatever it is called on your sytem), and you'll see that it works. – Andreas Rejbrand Jul 15 '13 at 14:31
  • Which version of Delphi are you using? Are you able to use the pre-canned routine in IOUtils? – David Heffernan Jul 15 '13 at 14:32
  • Possible duplicate of [Delete all files and folders recursively using Delphi](http://stackoverflow.com/questions/11798783/delete-all-files-and-folders-recursively-using-delphi) – LightBulb Jul 15 '13 at 14:35
  • Although deleting files recursively is this user's ultimate goal, @Lightbulb, that's not what *this* question is asking about. (In fact, this question specifically *excludes* recursion from the set of problems being discussed here.) This question is asking why FindFirst isn't returning the expected files, which ultimately has nothing to do with deletion or recursion. – Rob Kennedy Jul 15 '13 at 15:07
  • @LightBulb I'm specifically avoiding the confusion of file deletion from this question so that I can solve my problems one at a time. –  Jul 15 '13 at 15:19

1 Answers1

0

The path '\*.*' is relative to the root directory of the drive of the current working directory. You probably mean to pass GetCurrentDir + '\*' to FindFirst. Or even better, TPath.Combine(GetCurrentDir, '*').

For example, this program demonstrates that you code works correctly provided that you pass an appropriate path to FindFirst.

program FindFirstDemo;

{$APPTYPE CONSOLE}

uses
  SysUtils, IOUtils;

var
  SR: TSearchRec;

begin
  Writeln(GetCurrentDir);
  if FindFirst(TPath.Combine(GetCurrentDir, '*'),faAnyFile,SR)=0 then
  begin
    repeat
      Writeln(SR.Name);
    until FindNext(SR)<>0;
    FindClose(SR);
  end;
  Readln;
end.
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • This is still not finding any files. In response to your other comment, I'm not sure what version of Delphi this is, I'm using an acoustical measurement system called Praxis which allows you to write your own scripts to make the program do (ideally) whatever you'd like it to do. The script designer uses Delphi, however, and up till now I haven't had any trouble with coding. And I wasn't using IOUtils before, I was under the assumption that the FindFirst function was under the SysUtils unit? –  Jul 15 '13 at 15:16
  • To elaborate, the FileSearch function works successfully for me, but that function will only work if I am searching for a specific file. I am looking for a procedure that will give me the name of any file in a specified folder. –  Jul 15 '13 at 15:24
  • Did I not answer that? The code in this answer lists all objects in the current directory. – David Heffernan Jul 15 '13 at 15:55
  • If I copy this code and paste it into my script, I don't get any output return. So somehow it is working for you, but not for me :/ –  Jul 15 '13 at 16:21
  • The code in the answer is a complete program. Create a new console app. Replace the entire contents of the generated .dpr file with the code here, and you will get output. – David Heffernan Jul 15 '13 at 16:30
  • I'm now getting two EInOutErrors, 103 and 6 corresponding to the first Writeln and the Readln commands, respectively. My apologies if this is a hassle, I'm not familiar with this function. –  Jul 15 '13 at 18:06
  • I'm also getting an error that TPath and Combine are undeclared identifiers. If I replace that portion with the (GetCurrentDir+'\*') I only get the I/O errors –  Jul 15 '13 at 18:13
  • You need to do precisely what I said. Create a new console app. Paste in the code from the answer. You did not do that. You are running a GUI app. – David Heffernan Jul 15 '13 at 18:22
  • Forgive me, as I said before I'm using a system that simply has a script designer built in, not a Delphi scripting program. I'm not entirely sure how to create a console app rather than a GUI using this program. Do you know of any way to accomplish the same result using a GUI? –  Jul 15 '13 at 18:34
  • Well, now we are getting to the crux of your problem. You tagged the question Delphi, but now you tell us that it is not Delphi. I've no idea how to tell you to get this system that is unknown to me to run this code. I just gave you a Delphi answer. But all the same, the main idea in the answer stands, surely. That you were passing an invalid path to `FindFirst`. – David Heffernan Jul 15 '13 at 18:39
  • So, if the code in the question compiles and runs, you can make it **work** by changing the call to `FindFirst` as I described in the answer. To be precise it should be: `if (FindFirst(GetCurrentDir+'\*',faAnyFile,SR)=0) then` – David Heffernan Jul 15 '13 at 18:40
  • The program is using Delphi as the scripting language, it just isn't specifically Delphi developing software, forgive the miscommunication. I have tried just about every iteration of call for the FindFirst command and it still doesn't work. Correct me if I'm wrong, but if I put in an exact filename it should return 0, right? Ideally I'll be finding every file within a directory, but right now I can't even locate a single file with this command, even if I specify exactly what it is. –  Jul 15 '13 at 18:55