Search code examples
c#directoryreadonlydelete-directory

How do I delete a directory with read-only files in C#?


I need to delete a directory that contains read-only files. Which approach is better:

  • Using DirectoryInfo.Delete(), or,

  • ManagementObject.InvokeMethod("Delete")?

With DirectoryInfo.Delete(), I have to manually turn off the read-only attribute for each file, but ManagementObject.InvokeMethod("Delete") doesn't appear to need to. Is there any situation where one is more preferable to the other?

Sample code (test.txt is read only).

First way:

DirectoryInfo dir = new DirectoryInfo(@"C:\Users\David\Desktop\");
dir.CreateSubdirectory("Test");

DirectoryInfo test = new DirectoryInfo(@"C:\Users\David\Desktop\Test\");
File.Copy(@"C:\Users\David\Desktop\test.txt", @"C:\Users\David\Desktop\Test\test.txt");
File.SetAttributes(@"C:\Users\David\Desktop\Test\test.txt", FileAttributes.Archive);
test.Delete(true);

Second way:

DirectoryInfo dir = new DirectoryInfo(@"C:\Users\David\Desktop\");
dir.CreateSubdirectory("Test");

DirectoryInfo test = new DirectoryInfo(@"C:\Users\David\Desktop\Test\");
File.Copy(@"C:\Users\David\Desktop\test.txt", @"C:\Users\David\Desktop\Test\test.txt");

string folder = @"C:\Users\David\Desktop\Test";
string dirObject = "Win32_Directory.Name='" + folder + "'";
using (ManagementObject managementObject = new ManagementObject(dirObject))
{
    managementObject.Get();
    ManagementBaseObject outParams = managementObject.InvokeMethod("Delete", null,
    null);
    // ReturnValue should be 0, else failure
    if (Convert.ToInt32(outParams.Properties["ReturnValue"].Value) != 0)
    {
    }
}

Solution

  • Here is an extension method which sets Attributes to Normal recursively, then deletes the items:

    public static void DeleteReadOnly(this FileSystemInfo fileSystemInfo)
    {
        var directoryInfo = fileSystemInfo as DirectoryInfo;    
        if (directoryInfo != null)
        {
            foreach (FileSystemInfo childInfo in directoryInfo.GetFileSystemInfos())
            {
                childInfo.DeleteReadOnly();
            }
        }
    
        fileSystemInfo.Attributes = FileAttributes.Normal;
        fileSystemInfo.Delete();
    }