I am writing a service for Windows (from XP to 8.1). I need to recursively delete a folder and I use DeleteFile
and RemoveDirectory
for that.
I don't want to use SHFileOperation
because it has the MAX_PATH
limit.
The problem is that sometimes, RemoveDirectory
fails with ERROR_DIR_NOT_EMPTY
, even if the directory is empty.
I found out that this is because DeleteFile
works asynchronously, it only "marks" a file for deletion. Therefore, adding a small delay (Sleep) before calling RemoveDirectory
fixes the issue. But I am looking for a cleaner method.
So, is there a way to ensure that the marked files are well and truly deleted?
I already tried to call FlushFileBuffers
directly on the directory, without success.
Edit: Some are claiming that NtDeleteFile
can delete a file even if there are handles open on it. I just checked that and it's wrong, at least on Windows 8.1: the file is removed only when all the handles are closed.
On Vista+, you can (and should) use
IFileOperation
instead ofSHFileOperation()
. Then you are not limited to any path length limitations, and it can be used safely in a service, unlikeSHFileOperation()
:Is it wrong to call SHFileOperation from a service?
Is it wrong to call SHFileOperation from a service? Revised
So you decided to call SHFileOperation from a service, at least remember to disable copy hooks
Not really. The files are either in use, or not cleared from the cache manager, or the like.
If DeleteFile()
succeeds, you know the file will be deleted eventually. You just have to give the system time to actually delete it. If you receiveERROR_DIR_NOT_EMPTY
, wait a few seconds and try again. If you keep gettingERROR_DIR_NOT_EMPTY
after several attempts, either fail your operation since the folder is clearly not ready to be deleted yet, or else just keep trying until it finally succeeds, enumerating files periodically (in case new files are created).