Directory.Delete不起作用。访问被拒绝错误但在Windows资源管理器下它没关系

时间:2009-11-09 14:46:47

标签: c#

我搜索了SO但却一无所获。

为什么这不起作用?

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

以上行将抛出异常“访问被拒绝”。我有管理员权限,我可以用资源管理器删除目录。

看起来像一些禁止的字符?但Windows资源管理器可以处理它。如何删除名称相似的目录?

6 个答案:

答案 0 :(得分:22)

感谢大家的投入,它帮助我快速找到解决方案。

正如Phil所说“Directory.Delete如果失败,无论权限如何(参见msdn.microsoft.com/en-us/library/...的底部)”

此外Unable to remove Read-Only attribute from folder 微软说:

  

您可能无法删除   文件夹中的只读属性   使用Windows资源管理器此外,   某些程序可能会显示错误   尝试将文件保存到的消息   文件夹。

结论:在删除之前,始终删除所有目录,文件属性不同于Normal。所以下面的代码解决了这个问题:

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

答案 1 :(得分:5)

我使用了binball的代码并添加了一行来将目录属性设置为正常。

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

答案 2 :(得分:3)

根据您正在使用的目录,您可能需要管理员权限才能删除文件。要对此进行测试,请从资源管理器中以管理员身份运行您的应用,看看它是否有效(右键单击.exe并选择“以管理员身份运行”)。

如果可行,您需要在应用程序执行时获得管理员权限。您可以通过将以下内容添加到应用程序清单中来完成此操作:

<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
  <security>
    <requestedPrivileges>
      <requestedExecutionLevel level="requireAdministrator" />
    </requestedPrivileges>
  </security>
</trustInfo>

答案 3 :(得分:2)

您是否尝试创建DirectoryInfo类的新实例,然后在删除之前检查存在?代码如下所示:

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

另外,请确认您(运行应用程序的用户)有权访问该文件夹。如果这是网络映射驱动器,则需要能够由运行该应用程序的用户删除它。

希望这有帮助!

答案 4 :(得分:0)

我有这个症状,它实际上是explorer.exe本身锁定目录。我使用handle.exe找到了这个,但是也可以使用powershell来查找锁定文件的进程:

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

然后您必须决定是否尝试优雅地停止该过程;修改powershell脚本以试图杀死锁定文件的任何进程很容易:

$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 }}}

答案 5 :(得分:0)

添加到@binball和@Chuck答案。这是使用BFS遍历目录的setAttributesNormal()的异步友好实现。 非常适合进行深度目录遍历,在这种情况下递归可能会填充调用堆栈。

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