locked
IO.Directory.Delete - Read-only "Access Denied" RRS feed

  • Pergunta

  • I'm in the middle of a major project converting a VB6 application to .NET and have a requirement to delete a folder and its contents, in this case a complete user profile folder from C:\Documents and Settings.

    In VB6 I used the Scripting.FileSystemObject's DeleteFolder method successfully, however I'm unable to do so in .NET.

    I'm using the following function:

    Public Function DeleteFolder(ByVal strFolderName As String) As Boolean
       Try
           IO.Directory.Delete(strFolderName, True)
           Return True
       Catch ex As Exception
           Debug.Print(ex.Message)
           Return False
       End Try
    End Function

    Whenever I run this, I get an IOException "Access to the path '\\COMPUTERNAME\C$\Documents and Settings\USERNAME\Application Data\Microsoft\Internet Explorer\Quick Launch' is denied."

    As usual, a (probably) very simple problem that's caused me several lost hours.

    Is there a way to get this working, or can someone help me with a replacement routine that will recursively delete the folder's contents, taking care of permissions and read-only issues on-the-fly?

    Thanks!
    terça-feira, 20 de março de 2007 04:18

Respostas

  • Note: Expection handling missing 

    public
    static bool DeleteDirectory(string Path)
    {
          if (Directory.Exists(Path))
          {
            try{
                 ClearAttributes(Path);
                 Directory.Delete(Path, true);
                }
           catch (IOException e){
                Console.WriteLine(e.Message);
                return false;
                }
         }
         return true;
    }

     

    public static void ClearAttributes(string currentDir)
    {
       if (Directory.Exists(currentDir))
       {
           string[] subDirs = Directory.GetDirectories(currentDir);
           foreach(string dir in subDirs)
           ClearAttributes(dir);
           string[] files = files = Directory.GetFiles(currentDir);
           foreach (string file in files)
           File.SetAttributes(file, FileAttributes.Normal);
       }
    }

    • Editado raza.mirza terça-feira, 12 de maio de 2009 23:50
    • Marcado como Resposta Martin Xie - MSFT quarta-feira, 13 de maio de 2009 07:11
    terça-feira, 12 de maio de 2009 23:49
  • You try to run the app as a administrator. The directory and any file in it could not be locked, readonly and being using by other app.

     

    terça-feira, 27 de março de 2007 09:48
  • FYI: I ran into this issue too. The reason is that application data is a hidden folder. If you try to browse through all files and set them to a normal attribute as others has explained above it works for all but hidden and system. Same thing for directories.

    You have to somehow include hidden and system directories (and files) in your collection that you loop through. Im not sure how to do it myself but I would really like to know.

    Thanks all!
    • Sugerido como Resposta raza.mirza terça-feira, 12 de maio de 2009 23:05
    • Marcado como Resposta Martin Xie - MSFT quarta-feira, 13 de maio de 2009 07:11
    quinta-feira, 3 de julho de 2008 13:34

Todas as Respostas

  • You are accessing the folder remotely through the default C: drive share name ("C$").  I'm fairly sure you don't have any rights whatsoever when you use that share.  Does this work with the same path in VB6?
    terça-feira, 20 de março de 2007 05:40
  • That's not the issue, it works fine with VB6. Also works if I manually map to C$ and delete the folder through explorer, it's only the IO.directory.delete method that fails.

    Note that manually mapping to the drive and deleting the folder isn't an option for the application's target users.

    Also worth noting is that the function IO.Directory.Move, performed on the exact same folder to rename rather than delete a user's profile folder works (also using the C$ share).

    terça-feira, 20 de março de 2007 06:26
  • You try to run the app as a administrator. The directory and any file in it could not be locked, readonly and being using by other app.

     

    terça-feira, 27 de março de 2007 09:48
  • I was actually running the app as administrator, and as I said manually doing the same thing works perfectly, so there's no apparent permissions issues, locked or in use files etc.

     

    In the end I wrote my own recursive delete directory function which works flawlessly on the same folders.

     

    I still don't know WHY IO.Directory.Delete failed, but I'm coming to the conclusion that it just isn't very good.

     

    quinta-feira, 5 de abril de 2007 09:35
  • It seems that Directory.Delete is not able to delete a directory and its contents. It does work like the rd shell command which does not remove folders with content in it.

     

    Did you try the overloaded function Directory.Delete(Path,true) which should be able to recursive delete do this?

     

    Yours,

        Alois Kraus

     

    quinta-feira, 5 de abril de 2007 11:36
  • I did indeed try that, and it didn't work.

     

    That is to say, it worked in many cases, but failed when deleting a profile folder, even though I was able to delete the same folder through Explorer and via my own function (that I ended up making to do what Directory.Delete supposedly should do).

     

    Seems to me there's something specifically tricky about profile folders that confuses Directory.Delete, but the only feedback I get is "access denied", which doesn't help me.

     

    Never mind.

    quinta-feira, 5 de abril de 2007 12:30
  • I cannot repro the problem in the VB.NET 2005. No matter that I specify local path or UNC path as well as different folder location, as long as the directory exists and can be writen and not being used, it always can be deleted successfully.

    Public Class Form1

     

        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

            'System.IO.Directory.Delete("\\Martin\\c$\\Documents and Settings\\111", True)

            ' Call DeleteFolder("C:\\Documents and Settings\\111")

            ' Call DeleteFolder("\\Martin\\c$\\Documents and Settings\\111")

            ' Call DeleteFolder("C:\\Documents and Settings\\v-maxie\\My Documents\\111")

            Call DeleteFolder("\\Martin\\c$\\Documents and Settings\\v-maxie\\My Documents\\111")

     

        End Sub

     

        Public Function DeleteFolder(ByVal strFolderName As String) As Boolean

            Try

                IO.Directory.Delete(strFolderName, True)

                Return True

            Catch ex As Exception

                Debug.Print(ex.Message)

                Return False

            End Try

        End Function

     

    End Class

     

    I introduce you about the “Process Monitor” tool to check further. 

    The tool is an advanced monitoring tool for Windows that shows real-time file system, Registry and process/thread activity.

    It is a very useful utility for troubleshooting.

    http://www.microsoft.com/technet/sysinternals/processesandthreads/processmonitor.mspx

    • Não Marcado como Resposta Martin Xie - MSFT quarta-feira, 13 de maio de 2009 07:11
    sexta-feira, 6 de abril de 2007 06:51
  • Hi

    I have the same issue with C#.NET2.0....

    Did you find the source of this?

    I have all the permissions and ownership on folder (It is a "Roaming profile" folder), I can move it, I can delete manually....

    I get the same exception.

    This is a very frustrating issue...

    Can you help me with this please?

    segunda-feira, 14 de maio de 2007 08:02
  • Hi

    I am facing the same issue.

    However I have found out what causes the error.

    When you delete a directory that is "read only" you will get the above error.

    This is not a problem when deleting an empty directory as it would be fairly easy to determine if the attribute is set, but when you use the overloaded method, that deletes subdirectories it becomes far more tricky as the method stops is it encounters a "read only" Directory in the structure it deletes.

     

    Profiles always contains folders wich are "read only" and because of this the delete method will always fail.

     

    Does anyone know of a method to remove the read only flag on alle subdirectories?

     

    Best regards

    Daniel

    • Sugerido como Resposta Sea Lau quinta-feira, 8 de novembro de 2012 09:14
    quarta-feira, 16 de maio de 2007 07:55
  • You could just change the attributes of the hidden, system and read-only files:

          System.IO.File.SetAttributes(path, System.IO.FileAttributes.Normal);
    quarta-feira, 16 de maio de 2007 11:51
  • FYI: I ran into this issue too. The reason is that application data is a hidden folder. If you try to browse through all files and set them to a normal attribute as others has explained above it works for all but hidden and system. Same thing for directories.

    You have to somehow include hidden and system directories (and files) in your collection that you loop through. Im not sure how to do it myself but I would really like to know.

    Thanks all!
    • Sugerido como Resposta raza.mirza terça-feira, 12 de maio de 2009 23:05
    • Marcado como Resposta Martin Xie - MSFT quarta-feira, 13 de maio de 2009 07:11
    quinta-feira, 3 de julho de 2008 13:34
  • Note: Expection handling missing 

    public
    static bool DeleteDirectory(string Path)
    {
          if (Directory.Exists(Path))
          {
            try{
                 ClearAttributes(Path);
                 Directory.Delete(Path, true);
                }
           catch (IOException e){
                Console.WriteLine(e.Message);
                return false;
                }
         }
         return true;
    }

     

    public static void ClearAttributes(string currentDir)
    {
       if (Directory.Exists(currentDir))
       {
           string[] subDirs = Directory.GetDirectories(currentDir);
           foreach(string dir in subDirs)
           ClearAttributes(dir);
           string[] files = files = Directory.GetFiles(currentDir);
           foreach (string file in files)
           File.SetAttributes(file, FileAttributes.Normal);
       }
    }

    • Editado raza.mirza terça-feira, 12 de maio de 2009 23:50
    • Marcado como Resposta Martin Xie - MSFT quarta-feira, 13 de maio de 2009 07:11
    terça-feira, 12 de maio de 2009 23:49
  • I had the same problem as everyone else and that second function worked for me.

    public static void ClearAttributes( string currentDir)
    {
       if ( Directory .Exists(currentDir))
       {
           string [] subDirs = Directory .GetDirectories(currentDir);
           foreach ( string dir in subDirs)
           ClearAttributes(dir);
           string [] files = files = Directory .GetFiles(currentDir);
           foreach ( string file in files)
           File .SetAttributes(file, FileAttributes .Normal);
       }
    }

    quinta-feira, 21 de maio de 2009 19:26
  • I have the same issue and set FileAttributes to Normal didn't work.

     

    quinta-feira, 1 de julho de 2010 09:27
  • Directory attributes must be set to normal too.
    • Sugerido como Resposta Brian.k sexta-feira, 2 de julho de 2010 05:15
    sexta-feira, 2 de julho de 2010 05:14
  • Just as a helpful note as I had to bang my head against this. Failed to delete due to hidden/readonly directory. I would say that the dot net library isn't brilliant in this job.

    Set the attributes for the directory to normal as per previous post:

    System.IO.File.SetAttributes(DirectoryPath, System.IO.FileAttributes.Normal);

    Directory

     

    .Delete(DirectoryPath, true);

    • Sugerido como Resposta ShawnCurranGlasgow segunda-feira, 27 de fevereiro de 2012 14:53
    • Não Sugerido como Resposta ShawnCurranGlasgow segunda-feira, 27 de fevereiro de 2012 14:53
    • Sugerido como Resposta Sea Lau quinta-feira, 8 de novembro de 2012 09:15
    segunda-feira, 17 de janeiro de 2011 13:43
  •    

    Had the same problem deleting user profiles and created the below sub to get round it!

    Private Sub deleteWindowsDirectory(ByVal path As String) Try Dim t = My.Computer.FileSystem.GetDirectories(path, FileIO.SearchOption.SearchAllSubDirectories) 'iterate through the files of the top level path Dim a = My.Computer.FileSystem.GetFiles(path) For c As Integer = 0 To a.Count - 1 Dim p = My.Computer.FileSystem.GetFileInfo(a.Item(c)) p.Attributes = IO.FileAttributes.Normal Next 'iterate through sub dirs and and files in the sub dirs. For i As Integer = 0 To t.Count - 1 Dim r = My.Computer.FileSystem.GetDirectoryInfo(t.Item(i)) r.Attributes = IO.FileAttributes.Normal Dim g = My.Computer.FileSystem.GetFiles(t.Item(i)) For c As Integer = 0 To g.Count - 1 Dim p = My.Computer.FileSystem.GetFileInfo(g.Item(c)) p.Attributes = IO.FileAttributes.Normal Next Next My.Computer.FileSystem.DeleteDirectory(path, FileIO.DeleteDirectoryOption.DeleteAllContents) Catch ex As Exception MsgBox(ex.Message) End Try End Sub


    segunda-feira, 27 de fevereiro de 2012 15:04
  • The following code is a fix to the C# code posted above by Raza. This will recursively look through each folder from the top down, marking files and folders as normal.

    I tested this on a .V2 roaming profile folder.

            private void ClearAttributes(string strDest)
            {
                if (Directory.Exists(strDest))
                {
                    DirectoryInfo diFolder = new DirectoryInfo(strDest);
                    diFolder.Attributes = FileAttributes.Normal;
                    string[] files = files = Directory.GetFiles(strDest);
                    foreach (string file in files)
                    {
                        File.SetAttributes(file, FileAttributes.Normal);
                    }
                    string[] subDirs = Directory.GetDirectories(strDest);
    
                    foreach (string dir in subDirs)
                    {
                        ClearAttributes(dir);
                    }
                }
            }


    • Editado Nathan McKaskle quarta-feira, 5 de fevereiro de 2014 21:33
    • Sugerido como Resposta Daniel_CH quinta-feira, 30 de julho de 2020 16:30
    quarta-feira, 5 de fevereiro de 2014 21:32
  • Thanks! Did now work with your code ;-)
    quinta-feira, 30 de julho de 2020 16:31