Delete Directory with non empty subdirectory and files

How to delete one directory having some files and some non empty sub directory. I have tried SHFileOperation Function. It has some compatibility issue in Windows 7. Then I have tried IFileOperation Interface. But it is not compatible in Windows XP. Then I have tried the following codes as suggested by David Heffernan :

procedure TMainForm.BitBtn01Click(Sender: TObject);
  FileAndDirectoryExist: TSearchRec;
  ResourceSavingPath : string;
  ResourceSavingPath := (GetWinDir) + 'Web\Wallpaper\';
  if FindFirst(ResourceSavingPath + '\*', faAnyFile, FileAndDirectoryExist) = 0 then
      if (FileAndDirectoryExist.Name <> '.') and (FileAndDirectoryExist.Name <> '..') then
        if (FileAndDirectoryExist.Attr and faDirectory) <> 0 then
          //it's a directory, empty it
          ClearFolder(ResourceSavingPath +'\' + FileAndDirectoryExist.Name, mask, recursive)
          //it's a file, delete it
          DeleteFile(ResourceSavingPath + '\' + FileAndDirectoryExist.Name);
    until FindNext(FileAndDirectoryExist) <> 0;
    //now that this directory is empty, we can delete it

But it does not get compiled mentioning error as Undeclared Identifier at ClearFolder, mask and recursive. My requirement is to that "If any sub folder exist under WALLPAPER folder it will be deleted". The same sub folder may contain any number of non empty sub folder or files.


Well, for starters, SHFileOperation has no compatibility issues on Windows 7 or Windows 8. Yes, you are now recommended to use IFileOperation instead. But if you want to support older operating systems like XP, then you can and should just call SHFileOperation. It works and will continue to work. It's pefectly fine to use it on Windows 7 and Windows 8 and I'll eat my hat if it's ever removed from Windows. Microsoft go to extraordinary lengths to maintain backwards compatibility. So, SHFileOperation is your best option in my view.

Your FindFirst based approach fails because you need to put it in a separate function in order to allow recursion. And the code I posted in that other answer is incomplete. Here is a complete version:

procedure DeleteDirectory(const Name: string);
  F: TSearchRec;
  if FindFirst(Name + '\*', faAnyFile, F) = 0 then begin
        if (F.Attr and faDirectory <> 0) then begin
          if (F.Name <> '.') and (F.Name <> '..') then begin
            DeleteDirectory(Name + '\' + F.Name);
        end else begin
          DeleteFile(Name + '\' + F.Name);
      until FindNext(F) <> 0;

This deletes a directory and its contents. You'd want to walk the top level directory and then call this function for each subdirectory that you found.

Need Your Help

Does directly visiting a url have the same effect as navigating via a link?

ruby-on-rails ruby ruby-on-rails-4 path routes

I have a voting system which records users' ip addresses, users can only vote once. If the array of votes contains the user's ip address, then the voting link will not be displayed to the user:

How modify an angular element, as a ng-repeat element, by jQuery?

javascript jquery angularjs angularjs-ng-repeat domready

I think the problem is that angular creates these elements with javascript, so after the jQuery domready. So jQuery doesn't see those elements into the DOM.

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.