Cannot delete directory with Directory.Delete(path, true)

Jason Anderson picture Jason Anderson · Nov 30, 2008 · Viewed 246.2k times · Source

I'm using .NET 3.5, trying to recursively delete a directory using:

Directory.Delete(myPath, true);

My understanding is that this should throw if files are in use or there is a permissions problem, but otherwise it should delete the directory and all of its contents.

However, I occasionally get this:

System.IO.IOException: The directory is not empty.
    at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
    at System.IO.Directory.DeleteHelper(String fullPath, String userPath, Boolean recursive)
    at System.IO.Directory.Delete(String fullPath, String userPath, Boolean recursive)
    ...

I'm not surprised that the method sometimes throws, but I'm surprised to get this particular message when recursive is true. (I know the directory is not empty.)

Is there a reason I'd see this instead of AccessViolationException?

Answer

Jeremy Edwards picture Jeremy Edwards · Nov 30, 2008

Editor's note: Although this answer contains some useful information, it is factually incorrect about the workings of Directory.Delete. Please read the comments for this answer, and other answers to this question.


I ran into this problem before.

The root of the problem is that this function does not delete files that are within the directory structure. So what you'll need to do is create a function that deletes all the files within the directory structure then all the directories before removing the directory itself. I know this goes against the second parameter but it's a much safer approach. In addition, you will probably want to remove READ-ONLY access attributes from the files right before you delete them. Otherwise that will raise an exception.

Just slap this code into your project.

public static void DeleteDirectory(string target_dir)
{
    string[] files = Directory.GetFiles(target_dir);
    string[] dirs = Directory.GetDirectories(target_dir);

    foreach (string file in files)
    {
        File.SetAttributes(file, FileAttributes.Normal);
        File.Delete(file);
    }

    foreach (string dir in dirs)
    {
        DeleteDirectory(dir);
    }

    Directory.Delete(target_dir, false);
}

Also, for me I personally add a restriction on areas of the machine that are allowed to be deleted because do you want someone to call this function on C:\WINDOWS (%WinDir%) or C:\.