Link to home
Start Free TrialLog in
Avatar of SvanteMusic
SvanteMusic

asked on

Delete empty directory problem

Im using following two procedure/function to check if a directory is empty and to delete the empty directory.

But im getting an error message that the directory is in use by a program and can not be deleted. WHY?

I suspect that its my program that have the rights and stops the "delete", how to get around this ?

function IsDirEmpty (const ADirPath :string) :boolean;
var F :TSearchRec;
begin
  result := (FindFirst(ADirPath+'\*.*',faAnyFile,F) = 0) and
            (FindNext(F) = 0) and
            (FindNext(F) <> 0);
  FindClose(F);
end;

function DeleteFolder(FolderName: String; LeaveFolder: Boolean): Boolean;
var
  r: TshFileOpStruct;
begin
  Result := False;
  if not DirectoryExists(FolderName) then
    Exit;
  if LeaveFolder then
    FolderName := FolderName + ' *.* '
  else
  if FolderName[Length(FolderName)] = ' \ ' then
    Delete(FolderName,Length(FolderName), 1);
  FillChar(r, SizeOf(r), 0);
  r.wFunc := FO_DELETE;
  r.pFrom := PChar(FolderName);
  r.fFlags := FOF_ALLOWUNDO or FOF_NOCONFIRMATION; // or FOF_SILENT
  Result := ((ShFileOperation(r) = 0) and (not r.fAnyOperationsAborted));
end;
Avatar of SimesA
SimesA

I don't understand why, but the problem doesn't happen if you re-structure the IsDirEmpty routine to:

function IsDirEmpty(const ADirPath: string): boolean;
var
  F: TSearchRec;
begin
  result := (FindFirst(ADirPath + '\*.*', faAnyFile, F) = 0);
  try
    result := result and (FindNext(F) = 0);
    result := result and (FindNext(F) <> 0);
  finally
    FindClose(F);
  end;
end;

Perhaps the optimiser is getting in the way?
Avatar of SvanteMusic

ASKER

Tried your function, but the same error arrives.

Cant delete directory, is in use...
More info

Before i check if the directory is empty i am seeking for files in a choosen path with subdirs. And if it finds any files with extension *.mp3 it moves this files to another directory and checks later if the directory is empty. If so i want to delete it, otherwise leave it.
More info

Before i check if the directory is empty i am seeking for files in a choosen path with subdirs. And if it finds any files with extension *.mp3 it moves this files to another directory and checks later if the directory is empty. If so i want to delete it, otherwise leave it.
I have been trying to delete an empty directory this last week. All I kept getting was an I/O error message. The operating system makes the directory you are trying to delete the Current Directory as you have been searching through it and you cannot delete the current directory. Perhaps you could use SetCurrentDir() to change the current directory to something else and the delete the directory you don't want by reference. Just a thought as I have not yet tried it.
SetCurrentDir didnt help.

If i try to delete the directory in Windows Explorer not through my program i also get an error when my program is running.

But i can delete the directory when i close my program.
So its my prg that "closes" my possibilities to delete the directory.

Any more suggestions ?
Avatar of Tomas Helgi Johannsson
Is there any hidden file in that directory ? ;)

Regards,
  Tomas Helgi
Nope
The above example you mention is working as a standalone but not in my program.

I also use following before i run the two functions mention in the first letter.
Is there something that locks the directories from being deleted ?

procedure GetAllFiles(mask: string);
var
  search: TSearchRec;
  directory: string;
begin
  directory := ExtractFilePath(mask);

  // find all files
  if FindFirst(mask, $23, search) = 0 then
  begin
    repeat
      // add the files to the listbox
      Form1.ListBox1.Items.Add(directory + search.Name);
      Inc(Count);
    until FindNext(search) <> 0;
  end;

  // Subdirectories/ Unterverzeichnisse
  if FindFirst(directory + '*.*', faDirectory, search) = 0 then
  begin
    repeat
      if ((search.Attr and faDirectory) = faDirectory) and (search.Name[1] <> '.') then
        GetAllFiles(directory + search.Name + '\' + ExtractFileName(mask));
    until FindNext(search) <> 0;
    FindClose(search);
  end;
end;
Well, I can't say I immediately see the problem, but one thing strikes me:

    result := result and (FindNext(F) = 0);
   result := result and (FindNext(F) <> 0);

I would not use this construction (you'll get the . and .. as well, so the directory might not seem empty).

And I suspect that one of your procedures is still having a handle open to the directory you want to delete. Can't say which one, since I haven't really dug through all your code above, and I don't have the rest of your source either, which might also have a handle still open. But you could try the Process Explorer from www.sysinternals.com, which will immediately tell you if your process still has handles open to your directory when you want to delete it.

HTH,
Stef
Hi, a while ago but now with little more information

I now know that a handle is holding the directory and it happens in procedure GetAllFiles (Used Process Explorer, thanks Tvigep).

Im cant see where it fails, perhaps blind.
Anyone who wants the points perhaps can help me see again : - ) ?



procedure GetAllFiles(mask: string);
var
 search: TSearchRec;
 directory: string;
begin
 directory := ExtractFilePath(mask);

 // find all files
 if FindFirst(mask, $23, search) = 0 then
 begin
   repeat
     // add the files to the listbox
     Form1.ListBox1.Items.Add(directory + search.Name);
     Inc(Count);
   until FindNext(search) <> 0;
 end;

 // Subdirectories/ Unterverzeichnisse
 if FindFirst(directory + '*.*', faDirectory, search) = 0 then
 begin
   repeat
     if ((search.Attr and faDirectory) = faDirectory) and (search.Name[1] <> '.') then
       GetAllFiles(directory + search.Name + '\' + ExtractFileName(mask));
   until FindNext(search) <> 0;
   FindClose(search);
 end;
end;
ASKER CERTIFIED SOLUTION
Avatar of Tvigep
Tvigep
Flag of Netherlands image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thank for your help.

It didnt help adding a FindClose(search), but it was pointing me to a direction to find the error.

It was a DirectoryEdit (RxLib) that was holding the handle that i used to choose from and to directory to move my files.

I exchanged it to a buttonEdit and LMDSearchDialog and it solved my problem. But without your help TvigeP i would never find it. It was a good learn-lesson about handles for me.

Thanx