?
Solved

Delete empty directory problem

Posted on 2003-03-02
13
Medium Priority
?
375 Views
Last Modified: 2010-04-04
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;
0
Comment
Question by:SvanteMusic
13 Comments
 
LVL 1

Expert Comment

by:SimesA
ID: 8053278
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?
0
 

Author Comment

by:SvanteMusic
ID: 8053629
Tried your function, but the same error arrives.

Cant delete directory, is in use...
0
 

Author Comment

by:SvanteMusic
ID: 8053648
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.
0
2018 Annual Membership Survey

Here at Experts Exchange, we strive to give members the best experience. Help us improve the site by taking this survey today! (Bonus: Be entered to win a great tech prize for participating!)

 

Author Comment

by:SvanteMusic
ID: 8053740
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.
0
 

Expert Comment

by:KCBrecks
ID: 8056515
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.
0
 

Author Comment

by:SvanteMusic
ID: 8057418
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 ?
0
 
LVL 26

Expert Comment

by:Tomas Helgi Johannsson
ID: 8057584
Is there any hidden file in that directory ? ;)

Regards,
  Tomas Helgi
0
 

Author Comment

by:SvanteMusic
ID: 8057738
Nope
0
 

Author Comment

by:SvanteMusic
ID: 8060156
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;
0
 
LVL 2

Expert Comment

by:Tvigep
ID: 8062766
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
0
 

Author Comment

by:SvanteMusic
ID: 8098996
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;
0
 
LVL 2

Accepted Solution

by:
Tvigep earned 600 total points
ID: 8101209
Try to close the first FindFirst as well:

 // 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;

//This might help???
FindClose(search);

// 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);
0
 

Author Comment

by:SvanteMusic
ID: 8102875
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
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
The Relationships Diagram is a good way to get an overall view of what a database is keeping track of. It is also where relationships are defined. A relationship specifies how two tables connect to each other. As you build tables in Microsoft Ac…
Get the source code for a fully functional Access application shell with several popular security features that Access VBA application developers desire, but find difficult or impossible to figure out how to code. You get the source code for managi…
Suggested Courses

594 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question