Click to See Complete Forum and Search --> : Implementing RemoveDirectory to handle non empty directories


Rob Wainwright
June 6th, 1999, 03:53 PM
Hi,

I needed to write a routine to delete a directory (even if it contained files and directories) which the Win32 API couldn't do. I digged up a recursive directory walker class that I had which supports bottom up recursion and used ::DeleteFile and ::RemoveDirectory on the walk back up the tree.

The algorithm is correct, but sometimes the RemoveDirectory call is returning DIRECTORY_NOT_EMPTY.

If I press refresh on explorer, I can visually see that the directory isn't empty.

If I insert a Sleep command within the tree walk, the directories all delete okay.

I've tried adding _flushall commands but that doesn't seem to have any effect.

Anyway, as I needed the algorithm for work, I sorted it using a brute force algorithm (i.e. running the recursion a number of times until all
the directories and files are deleted).

But I'd like to know why the RemoveDirectory sometimes returns DIRECTORY_NOT_EMPTY (probably because of caching) and how to flush the cache (or whatever is needed).

Thanks
Rob.

Todd Jeffreys
June 6th, 1999, 03:56 PM
BOOL WINAPI DeleteDirectory(LPCTSTR lpszDir)
{
WIN32_FIND_DATA find;
BOOL bFound=TRUE;
HANDLE hFind=INVALID_HANDLE_VALUE;

ZeroMemory(&find,sizeof(find));

if (!SetCurrentDirectory(lpszDir)) return FALSE;

hFind=FindFirstFile("*.*",&find);
if (hFind == INVALID_HANDLE_VALUE)
{
SetCurrentDirectory("..");
return FALSE;
}

while (bFound)
{
if (find.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if ((lstrcmp(find.cFileName,".") != 0) && (lstrcmp(find.cFileName,"..") != 0))
{
DeleteDirectory(find.cFileName);
}
}
else DeleteFile(find.cFileName);
bFound=FindNextFile(hFind,&find);
}
FindClose(hFind);
SetCurrentDirectory("..");
return RemoveDirectory(lpszDir);
}

Rob Wainwright
June 6th, 1999, 04:02 PM
This is pretty much the algorithm that I have got. The only interesting difference is that I'm not using Get/SetCurrentDirectory. Unfortunately, the app I've got is multithreaded with god knows how many different people accessing the file system, so we're banned from playing with the shared current directory resource.

Do you think the SetCurrentDirectory call could be flushing things ?

Todd Jeffreys
June 6th, 1999, 05:19 PM
To flush what? I don't think it causes any flushing of the file system. The call to SetCurrentDirectory just allows me to delete files without giving a full path name. So when i recurse, i just change the directories and I don't have to worry about maintaining a string that has the current path in it.

mharishkumarreddy
March 23rd, 2006, 12:09 AM
Hello,

Me too, Iam getting the same error, in my case iam using ZwSetInformationFile to set the delete flag on the directory.

But this call is failing by saying that DIRECOTRY_NOT_EMPTY ...even though i have called the ZwSetInformationFile which sets delete flag on all the files inside the direcotry. can you please tell me where exactly you are using the Sleep with in the tree walk. I mean are you first recursively trying to delete the directory, sleep,and then again recursively delete the directory?

golanshahar
March 23rd, 2006, 01:08 AM
Hi,

I needed to write a routine to delete a directory (even if it contained files and directories) which the Win32 API couldn't do. I digged up a recursive directory walker class that I had which supports bottom up recursion and used ::DeleteFile and ::RemoveDirectory on the walk back up the tree.


use ::SHFileOperation() (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/functions/shfileoperation.asp).

Cheers