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); var FileAndDirectoryExist: TSearchRec; ResourceSavingPath : string; begin ResourceSavingPath := (GetWinDir) + 'Web\Wallpaper\'; if FindFirst(ResourceSavingPath + '\*', faAnyFile, FileAndDirectoryExist) = 0 then try repeat 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) else //it's a file, delete it DeleteFile(ResourceSavingPath + '\' + FileAndDirectoryExist.Name); until FindNext(FileAndDirectoryExist) <> 0; //now that this directory is empty, we can delete it RemoveDir(ResourceSavingPath); finally FindClose(FileAndDirectoryExist); end; end;
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.
Answers
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); var F: TSearchRec; begin if FindFirst(Name + '\*', faAnyFile, F) = 0 then begin try repeat if (F.Attr and faDirectory <> 0) then begin if (F.Name <> '.') and (F.Name <> '..') then begin DeleteDirectory(Name + '\' + F.Name); end; end else begin DeleteFile(Name + '\' + F.Name); end; until FindNext(F) <> 0; finally FindClose(F); end; RemoveDir(Name); end; end;
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.