26

I have searched the SO but find nothing.

Why this doesn't work?

Directory.Delete(@"E:\3\{90120000-001A-0000-0000-0000000FF1CE}-C");

Above line will throw exception "Access is denied". I have admin rigths and I can delete the dir with Explorer.

It looks like some forbidden chars? but Windows Explorer can handle it. How can I delete directories with names like that?

Taryn
  • 242,637
  • 56
  • 362
  • 405
binball
  • 2,255
  • 4
  • 30
  • 34
  • 2
    Is the directory empty? Did you tried to "trace" with sysinternal tools? – Arthur Nov 09 '09 at 14:49
  • Yes, dir is empty. I didn't think about sysinternals. Thx, I will try more tests soon (but maybe somebody will catch "the bug" earlier). – binball Nov 09 '09 at 14:52
  • 4
    Don't suppose the directory is read only? Directory.Delete fails if it is, regardless of permissions (see bottom of http://msdn.microsoft.com/en-us/library/fxeahc5f.aspx) – Phil Jenkins Nov 09 '09 at 14:54
  • 1
    Thank you Phil for your suggestion. That was exactly this.ReadOnly attribute on directory. I was fooled because of standard WindowsXP behaviour which show ReadOnly mark for every folder. So I "removed" this ReadOnly attribute by Windows Explorer but it still remains. Strange default WindowsXP setting.. Thank You! – binball Nov 09 '09 at 18:34
  • Another answer: http://stackoverflow.com/a/648055/3543437 – kayleeFrye_onDeck Jan 20 '16 at 21:47
  • Setting something to normal is better than trying to remove RO: http://stackoverflow.com/a/648055/3543437 – kayleeFrye_onDeck Jan 20 '16 at 21:50
  • I just had this error, but it turned out the antivirus was causing it - denying the access regardless of the permissions set – imma Jan 29 '18 at 15:09

6 Answers6

44

Thank you all for your input, it helps me in quick find of solution.

As Phil mentioned "Directory.Delete fails if it is, regardless of permissions (see bottom of msdn.microsoft.com/en-us/library/…)"

In addition Unable to remove Read-Only attribute from folder Microsoft says:

You may be unable to remove the Read-Only attribute from a folder using Windows Explorer. In addition, some programs may display error messages when you try to save files to the folder.

Conclusion: always remove all dir,file attributes diffrent then Normal before deleting. So below code solve the problem:

System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(@"E:\3\{90120000-0021-0000-0000-0000000FF1CE}-C1");

if (dir.Exists)
{
    setAttributesNormal(dir);
    dir.Delete(true);
}

. . .

function setAttributesNormal(DirectoryInfo dir) {
    foreach (var subDir in dir.GetDirectories())
        setAttributesNormal(subDir);
    foreach (var file in dir.GetFiles())
    {
        file.Attributes = FileAttributes.Normal;
    }
}
ChrisM
  • 1,148
  • 8
  • 22
binball
  • 2,255
  • 4
  • 30
  • 34
  • I get 'access denied' when I try to this. My application calls a process that creates a directory. At a later stage, I need to delete the directory and I get 'access denied'. Any solutions ? – rajkiran Dec 05 '16 at 23:59
  • 1
    Success! when I added following line at the end of `setAttributesNormal` function: `dir.Attributes = FileAttribute.Normal` – Imran Rafique Oct 16 '17 at 11:28
14

I used binball's code and added one line to set the directory attributes to normal also.

if (dir.Exists)
    {
        setAttributesNormal(dir);
        dir.Delete(true);
    }    

function setAttributesNormal(DirectoryInfo dir)
    {
        foreach (var subDir in dir.GetDirectories())
        {
            setAttributesNormal(subDir);
            subDir.Attributes = FileAttributes.Normal;
        }
        foreach (var file in dir.GetFiles())
        {
            file.Attributes = FileAttributes.Normal;
        }
    }
Chuck
  • 1,001
  • 1
  • 13
  • 19
  • I get 'access denied' when I try to this. My application calls a process that creates a directory. At a later stage, I need to delete the directory and I get 'access denied'. Any solutions ? – rajkiran Dec 05 '16 at 23:59
  • Make sure that the process does not leave any open connection to the files, otherwise you will run into issues. I'm sure that you have the correct level of access, like full control, etc... – Chuck Dec 13 '16 at 20:59
  • I would suggest since this is a directory recursive operation you should move the `subDir.Attributes = FileAttributes.Normal` line a the end of the function since that would also include the target directory and would be executed recursively. – Jeremy Aug 04 '17 at 15:08
  • 3
    Success! when I added following line at the end of `setAttributesNormal` function: `dir.Attributes = FileAttribute.Normal`. The function was missing main (parent) directory. – Imran Rafique Oct 16 '17 at 11:32
3

Based on the directory you are working in, you will probably need administrator access to delete files. To test this, run your app as administrator from explorer and see if it works (right-click the .exe and choose "Run As Administrator").

If that works, you'll need to get administrator privileges when your application executes. You can do this by adding the following to your application manifest:

<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
  <security>
    <requestedPrivileges>
      <requestedExecutionLevel level="requireAdministrator" />
    </requestedPrivileges>
  </security>
</trustInfo>
jheddings
  • 26,717
  • 8
  • 52
  • 65
3

Adding to @binball and @Chuck answer. Here is a somewhat quick async-friendly implementation of setAttributesNormal() using BFS to traverse directories. It's ideal for deep directory traversal, where recursion may fill call stack.

internal static void SetAttributesNormal(DirectoryInfo path) {
    // BFS folder permissions normalizer
    Queue<DirectoryInfo> dirs = new Queue<DirectoryInfo>();
    dirs.Enqueue(path);
    while (dirs.Count > 0) {
        var dir = dirs.Dequeue();
        dir.Attributes = FileAttributes.Normal;
        Parallel.ForEach(dir.EnumerateFiles(), e => e.Attributes = FileAttributes.Normal);
        foreach (var subDir in dir.GetDirectories())
            dirs.Enqueue(subDir);
    }
}
Keombre
  • 633
  • 6
  • 12
2

Have you tried to create a new instance of the DirectoryInfo class, and then checking the exists before the delete? The code would look like this:

        System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(@"E:\3\{90120000-001A-0000-0000-0000000FF1CE}-C");
        if (dir.Exists)
            dir.Delete(true);

Also, please verify that you (the user running the application) has access to the folder. If this is a network mapped drive, it will need to be able to be deleted by the user running the application.

Hope this helps!

Scott
  • 2,183
  • 18
  • 33
1

I had this symptom, and it actually was explorer.exe itself that was locking the directory. I found this using handle.exe, but one can also use powershell to find which process is locking the file:

$lockedFile = "C:\Windows\System32\wshtcpip.dll"
Get-Process | foreach{$processVar = $_; $_.Modules | foreach { if ($_.FileName -like "${lockedFile}*") { $processVar.Name + " PID:" + $processVar.id + " [" + $_.Filename + "]"}}}

You then have to decide whether to try to stop that process gracefully or not; it would be easy to modify the powershell script to try to kill any processes locking the file:

$lockedFile = "C:\directory_I_want_to_delete"
Get-Process | foreach{$processVar = $_; $_.Modules | foreach { if ($_.FileName -like "${lockedFile}*") { write-host $processVar.Name + " PID:" + $processVar.id + " [" + $_.Filename + "]" ; write-host "Killing process..." ; stop-process -pid $processVar.id -force }}}
mtd
  • 2,224
  • 19
  • 21
  • 1
    In my case explorer was opened to a parent folder, but maybe it keeps the lock since I previously visited the subfolder I need to delete. Now I know why the code randomly gives exception! :/ – Fil Jan 18 '23 at 15:19