In my app, I have built a system where users can create picture galleries. Photos held in folders in the format of category_name/gallery_name/{pictures} on disk. Each upload
This isn't as complete as I'd like, but these are things that have helped me in the past when I faced similar issues.
The file is in use by something else. This means you've created a folder/file and have not yet released it. Use .Close() (where applicable).
A lock related issue.
You have used the Directory.Delete(rootFolder, true)
(where true means delete recursively) when there are no folders within the root folder specified.
It is open by another program. Now, I have NO idea where to begin on this other than installing Process Monitor which can help but that only really works in some situations.
Things like Anti Virus, or even (on Windows) things like Defender have caused this issue in the past.
When you call Directory.Delete and a file is open in such way, Directory.Delete succeeds in deleting all files but when Directory.Delete calls RemoveDirectory a "directory is not empty" exception is thrown because there is a file marked for deletion but not actually deleted.
The obvious things includes make sure you have permission to delete the folder (not just you, but the account the program runs under).
The file you are trying to delete is readonly. Change the file attributes of all files in the folder first from read-only.
The path is shared by other Windows components so becareful where you are creating/deleting folders.
Source
Source
This works for me, even though i have File Explorer open:
public static void DeleteFilesAndFoldersRecursively(string target_dir)
{
foreach (string file in Directory.GetFiles(target_dir))
{
File.Delete(file);
}
foreach (string subDir in Directory.GetDirectories(target_dir))
{
DeleteFilesAndFoldersRecursively(subDir);
}
Thread.Sleep(1); // This makes the difference between whether it works or not. Sleep(0) is not enough.
Directory.Delete(target_dir);
}
You may just use Directory.Delete(target_dir, true);
to remove directory and all files recursively. You don't have to write custom function.
This issue was driving me crazy. I was seeing the EXACT behavior of the poster when using Directory.Delete(dirPath, recursive: true);
to delete a directory and it's contents. And just like the poster, even though the call threw an exception stating "Directory is not empty." the call had actually deleted all the contents of the directory recursively BUT failed to delete the root directory of the path provided. Craziness.
In my case I found that the issue was brought on by whether left nav tree in window's explorer showed the directory open which I was trying to delete. If so, then some sort of queued delete or caching of the delete of the directory's contents seems to be occurring causing the issue. This behavior can seem squirrely and unpredictable because viewing the directory in windows explorer that is to be deleted does not cause this issue as long as the directory is not open in the Windows left nav tree.
A few pictures are probably necessary to make this clear. Notice in the path below that the window is showing 1346. 1346 is a child directory of directory 1001. In this case a call to delete 1346 recursively will succeed because it's not an issue that we are looking at 1346 in Window's explorer per se.
But in the picture below, notice that in the path below we are looking at directory 1018. BUT in the left nave we have directory 1349 opened up (see arrow). THIS IS WHAT CAUSES THE ISSUE, at least for me. If in this situation we call Directory.Delete(dirPath, recursive: true);
for the dirPath
of directory 1349 it will throw a "Directory is not empty." exception. But if we check the directory after the exception occurrs we will find that it has deleted all the contents of the directory and it is in fact now empty.
So this seems very much like an edge case scenario but it's one we developers can run into because when we are testing code we are wanting to watch to see if the folder gets deleted. And it's challenging to understand what's triggering it because it's about the left nav bar of windows explorer not the main contents area of the window.
Anyway, as much as I dislike the code below, it does solve the problem for me in all cases:
//delete the directory and it's contents if the directory exists
if (Directory.Exists(dirPath)) {
try {
Directory.Delete(dirPath, recursive: true); //throws if directory doesn't exist.
} catch {
//HACK because the recursive delete will throw with an "Directory is not empty."
//exception after it deletes all the contents of the diretory if the directory
//is open in the left nav of Windows's explorer tree. This appears to be a caching
//or queuing latency issue. Waiting 2 secs for the recursive delete of the directory's
//contents to take effect solved the issue for me. Hate it I do, but it was the only
//way I found to work around the issue.
Thread.Sleep(2000); //wait 2 seconds
Directory.Delete(dirPath, recursive: true);
}
}
I hope this helps others. It took quite a bit of time to track down and explain because it's really odd behavior.
In my case, I have created my directory with my program running as administrator. When I tried to delete the same directory without administrator rights, I got the "Directory is not empty" error.
Solution: Either run the application as administrator or delete it manually.