61 votes

Comment puis-je supprimer un répertoire avec des fichiers en lecture seule en C#?

J'ai besoin de supprimer un répertoire qui contient des fichiers en lecture seule. L'approche qui est mieux: à l'aide de DirectoryInfo.Delete(), ou ManagementObject.InvokeMethod("Supprimer")? Avec DirectoryInfo.Supprimer, je dois l'éteindre manuellement l'attribut en lecture seule pour chaque fichier, mais ManagementObject.InvokeMethod("Supprimer") ne semble pas nécessaire. Est-il une situation où l'on est plus préférable à l'autre?

Exemple de code (test.txt est en lecture seule).

Première façon:

        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);

Deuxième façon:

        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)
            {
            }
        }

102voto

adrian Points 680

Façon la plus simple d'éviter les appels récursifs à l'est par l'utilisation de l' AllDirectories option lors de la prise en FileSystemInfos, comme suit:

public static void ForceDeleteDirectory(string path) 
{
    var directory = new DirectoryInfo(path) { Attributes = FileAttributes.Normal };

    foreach (var info in directory.GetFileSystemInfos("*", SearchOption.AllDirectories))
    {
        info.Attributes = FileAttributes.Normal;
    }

    directory.Delete(true);
}

96voto

Vitaliy Ulantikov Points 2834

J'ai écrit ma propre méthode qui définit les attributs à la normale pour chaque fichier et répertoire de façon récursive, et puis les supprime:

private static void DeleteFileSystemInfo(FileSystemInfo fileSystemInfo)
{
    var directoryInfo = fileSystemInfo as DirectoryInfo;    
    if (directoryInfo != null)
    {
        foreach (var childInfo in directoryInfo.GetFileSystemInfos())
        {
            DeleteFileSystemInfo(childInfo);
        }
    }

    fileSystemInfo.Attributes = FileAttributes.Normal;
    fileSystemInfo.Delete();
}

10voto

Frederic Arteau Points 51

J'espère que cela peut aider

private void DeleteRecursiveFolder(string pFolderPath)
    {
        foreach (string Folder in Directory.GetDirectories(pFolderPath))
        {
            DeleteRecursiveFolder(Folder);
        }

        foreach (string file in Directory.GetFiles(pFolderPath))
        {
            var pPath = Path.Combine(pFolderPath, file);
            FileInfo fi = new FileInfo(pPath);
            File.SetAttributes(pPath, FileAttributes.Normal);
            File.Delete(file);
        }

        Directory.Delete(pFolderPath);
    }

5voto

jasonk Points 51

Une autre méthode sans la nécessité de la récursivité.

public static void ForceDeleteDirectory(string path)
{
    DirectoryInfo root;
    Stack<DirectoryInfo> fols;
    DirectoryInfo fol;
    fols = new Stack<DirectoryInfo>();
    root = new DirectoryInfo(path);
    fols.Push(root);
    while (fols.Count > 0)
    {
        fol = fols.Pop();
        fol.Attributes = fol.Attributes & ~(FileAttributes.Archive | FileAttributes.ReadOnly | FileAttributes.Hidden);
        foreach (DirectoryInfo d in fol.GetDirectories())
        {
            fols.Push(d);
        }
        foreach (FileInfo f in fol.GetFiles())
        {
            f.Attributes = f.Attributes & ~(FileAttributes.Archive | FileAttributes.ReadOnly | FileAttributes.Hidden);
            f.Delete();
        }
    }
    root.Delete(true);
}

4voto

jdvatwork Points 31
private void DeleteRecursiveFolder(DirectoryInfo dirInfo)
{
    foreach (var subDir in dirInfo.GetDirectories())
    {
        DeleteRecursiveFolder(subDir);
    }

    foreach (var file in dirInfo.GetFiles())
    {
        file.Attributes=FileAttributes.Normal;
        file.Delete();
    }

    dirInfo.Delete();
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X