Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Delete empty directory problem

Posted on 2003-03-02
13
Medium Priority
?
359 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
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
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 

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 25

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

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

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…
Video by: ITPro.TV
In this episode Don builds upon the troubleshooting techniques by demonstrating how to properly monitor a vSphere deployment to detect problems before they occur. He begins the show using tools found within the vSphere suite as ends the show demonst…
Monitoring a network: how to monitor network services and why? Michael Kulchisky, MCSE, MCSA, MCP, VTSP, VSP, CCSP outlines the philosophy behind service monitoring and why a handshake validation is critical in network monitoring. Software utilized …
Suggested Courses

722 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