IT-Swarm.Net

无法使用Directory.Delete删除目录(路径,true)

我正在使用.NET 3.5,尝试使用以下命令递归删除目录:

Directory.Delete(myPath, true);

我的理解是,如果文件正在使用或存在权限问题,这应该抛出,否则它应该删除目录及其所有内容。.

但是,我偶尔会得到这个:

System.IO.IOException: The directory is not empty.
    at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
    at System.IO.Directory.DeleteHelper(String fullPath, String userPath, Boolean recursive)
    at System.IO.Directory.Delete(String fullPath, String userPath, Boolean recursive)
    ...

我对这种方法有时会抛出并不感到惊讶,但是当递归为真时,我很惊讶地得到这条特殊的信息。 (我 知道 目录不是空的。)

有没有理由我看到这个而不是AccessViolationException?

357
Jason Anderson

编者注: 虽然这个答案包含一些有用的信息,但事实上Directory.Delete的工作方式是不正确的。请阅读此答案的评论以及此问题的其他答案。.


我之前遇到过这个问题。.

问题的根源是此函数不会删除目录结构中的文件。因此,您需要做的是创建一个函数,在删除目录本身之前删除目录结构中的所有文件,然后删除所有目录。我知道这与第二个参数相反,但它是一种更安全的方法。此外,您可能希望在删除文件之前从文件中删除READ-ONLY访问属性。否则会引发异常。.

只需将此代码打入您的项目即可。.

public static void DeleteDirectory(string target_dir)
{
    string[] files = Directory.GetFiles(target_dir);
    string[] dirs = Directory.GetDirectories(target_dir);

    foreach (string file in files)
    {
        File.SetAttributes(file, FileAttributes.Normal);
        File.Delete(file);
    }

    foreach (string dir in dirs)
    {
        DeleteDirectory(dir);
    }

    Directory.Delete(target_dir, false);
}

另外,对我来说,我个人添加了对允许删除的机器区域的限制,因为你是否希望有人在C:\WINDOWS (%WinDir%)C:\上调用此函数。.

218
Jeremy Edwards

如果您尝试以递归方式删除目录a并且目录a\b在资源管理器中打开,则b将被删除,但是对于a,您将收到错误“目录不为空”,即使它在您去看看时是空的。任何应用程序的当前目录(包括资源管理器) 保留目录的句柄 。当你调用Directory.Delete(true)时,它会从下往上删除:b,然后是a。如果在资源管理器中打开b,资源管理器将检测到b的删除,向上更改目录cd ..并清理打开的句柄。由于文件系统异步操作,Directory.Delete操作因与Explorer冲突而失败。.

不完整的解决方案

我最初发布了以下解决方案,其中包含中断当前线程以允许Explorer时间释放目录句柄的想法。.

// incomplete!
try
{
    Directory.Delete(path, true);
}
catch (IOException)
{
    Thread.Sleep(0);
    Directory.Delete(path, true);
}

但这仅在打开目录是要删除的目录的立即子项时才有效。如果在资源管理器中打开a\b\c\d并在a上使用此项,则在删除dc后此方法将失败。.

一个更好的解决方案

即使在资源管理器中打开了其中一个较低级别的目录,此方法也将处理深层目录结构的删除。.

/// <summary>
/// Depth-first recursive delete, with handling for descendant 
/// directories open in Windows Explorer.
/// </summary>
public static void DeleteDirectory(string path)
{
    foreach (string directory in Directory.GetDirectories(path))
    {
        DeleteDirectory(directory);
    }

    try
    {
        Directory.Delete(path, true);
    }
    catch (IOException) 
    {
        Directory.Delete(path, true);
    }
    catch (UnauthorizedAccessException)
    {
        Directory.Delete(path, true);
    }
}

尽管我们自己进行了额外的递归工作,但我们仍然必须处理沿途可能发生的UnauthorizedAccessException。目前尚不清楚第一次删除尝试是否为第二次成功删除尝试铺平了道路,或者它是否仅仅是抛出/捕获允许文件系统赶上的异常所引入的时间延迟。.

您可以通过在try块的开头添加Thread.Sleep(0)来减少在典型条件下抛出和捕获的异常数。此外,存在一个风险,即在系统负载较重的情况下,您可能会通过Directory.Delete尝试两次尝试并失败。将此解决方案视为更强大的递归删除的起点。.

一般答案

此解决方案仅解决与Windows资源管理器交互的特性。如果你想要一个坚如磐石的删除操作,要记住的一点是,任何东西(病毒扫描程序,无论什么)都可以随时打开你想要删除的内容。所以你必须稍后再试。多久以后,您尝试多少次,取决于删除对象的重要性。 as MSDN表示

强大的文件迭代代码必须考虑到文件系统的许多复杂性。.

这个无辜的声明,只提供了NTFS参考文档的链接,应该让你的头发站起来。.

编辑 :很多。这个答案最初只有第一个不完整的解决方案。)

169
ryascl

在进一步研究之前,请检查您控制的以下原因:

  • 文件夹是否设置为进程的当前目录?如果是,请先将其更改为其他内容。.
  • 您是否从该文件夹中打开了文件(或加载了DLL)? (并忘了关闭/卸载它)

否则,请检查您无法控制的以下合法原因:

  • 该文件夹中有标记为只读的文件。.
  • 您没有对某些文件的删除权限。.
  • 文件或子文件夹在资源管理器或其他应用程序中打开。.

如果出现以上任何问题,您应该在尝试改进删除代码之前了解其原因。 应该 您的应用程序是删除只读或无法访问的文件?是谁标记了他们,为什么?

一旦排除了上述原因,仍然存在虚假失败的可能性。如果任何人拥有要删除的任何文件或文件夹的句柄,则删除将失败,并且有许多原因可能导致某人枚举该文件夹或读取其文件:

  • 搜索索引器
  • 反病毒软件
  • 备份软件

处理虚假失败的一般方法是多次尝试,在尝试之间暂停。你显然不想永远尝试,所以你应该在经过一定次数的尝试后放弃并抛出异常或忽略错误。像这样:

private static void DeleteRecursivelyWithMagicDust(string destinationDir) {
    const int magicDust = 10;
    for (var gnomes = 1; gnomes <= magicDust; gnomes++) {
        try {
            Directory.Delete(destinationDir, true);
        } catch (DirectoryNotFoundException) {
            return;  // good!
        } catch (IOException) { // System.IO.IOException: The directory is not empty
            System.Diagnostics.Debug.WriteLine("Gnomes prevent deletion of {0}! Applying magic dust, attempt #{1}.", destinationDir, gnomes);

            // see http://stackoverflow.com/questions/329355/cannot-delete-directory-with-directory-deletepath-true for more magic
            Thread.Sleep(50);
            continue;
        }
        return;
    }
    // depending on your use case, consider throwing an exception here
}

在我看来,这样的帮助应该用于所有删除,因为虚假的失败总是可能的。但是,您应该将此代码添加到您的使用案例中,而不是盲目地复制它。.

我的应用程序生成的内部数据文件夹的虚假失败,位于%LocalAppData%下,所以我的分析如下:

  1. 该文件夹仅由我的应用程序控制,并且用户没有正当理由去将该文件夹中的内容标记为只读或无法访问,因此我不会尝试处理该情况。.

  2. 那里没有有价值的用户创建的东西,所以不存在强行删除错误的东西的风险。.

  3. 作为一个内部数据文件夹,我不希望它在资源管理器中打开,至少我觉得不需要专门处理这种情况(即我通过支持很好地处理这种情况)。.

  4. 如果所有尝试都失败,我选择忽略该错误。最糟糕的情况是,该应用程序无法解压缩一些较新的资源,崩溃并提示用户联系支持,只要不经常发生,我就可以接受。或者,如果应用程序没有崩溃,它将留下一些旧数据,这也是我可以接受的。.

  5. 我选择将重试次数限制为500毫秒(50 * 10)。这是一个在实践中起作用的任意门槛;我希望阈值足够短,以便用户不会杀死应用程序,认为它已经停止响应。另一方面,半秒钟是罪犯完成处理我的文件夹的充足时间。从其他SO答案来看,有时候甚至Sleep(0)都可以接受,很少有用户会经历多次重试。.

  6. 我每50ms重试一次,这是另一个任意数字。我觉得如果一个文件正在处理(索引,检查),当我尝试删除它时,50ms是在我的情况下期望完成处理的正确时间。此外,50ms足够小,不会导致明显的减速;再次,Sleep(0)在许多情况下似乎已经足够了,所以我们不想拖延太多。.

  7. 代码重试任何IO例外。我通常不希望任何异常访问%LocalAppData%,因此我选择简单并接受500毫秒延迟的风险,以防发生合法异常。我也不想找到一种方法来检测我想要重试的确切异常。.

40
Andrey Tarantsov

应该提到的一件重要事情(我将其添加为注释,但我不允许)是重载的行为从.NET 3.5更改为.NET 4.0。.

Directory.Delete(myPath, true);

从.NET 4.0开始,它删除文件夹本身但不在3.5中的文件。这也可以在MSDN文档中看到。.

.NET 4.0

删除 指定的目录 ,如果指示,则删除目录中的所有子目录和文件。.

.NET 3.5

删除 空目录 ,如果指示,则删除目录中的所有子目录和文件。.

15
jettatore

我在Delphi下遇到了同样的问题。最终的结果是我自己的应用程序锁定了我想要删除的目录。不知何故,当我写入目录时,目录被锁定(一些临时文件)。.

在删除它之前,我做了一个简单的 更改目录 到它的父目录。.

13
Drejc

我很惊讶没有人想到这个简单的非递归方法,它可以删除包含只读文件的目录,而无需更改每个文件的只读属性。.

Process.Start("cmd.exe", "/c " + @"rmdir /s/q C:\Test\TestDirectoryContainingReadOnlyFiles"); 

(稍微更改一下,不要暂时触发cmd窗口,这可以通过互联网获得)

11
Piyush Soni

现代异步答案

接受的答案是完全错误的,它可能适用于某些人,因为从磁盘获取文件所花费的时间可以释放锁定文件的任何内容。事实是,这是因为文件被某些其他进程/流/操作锁定。其他答案使用Thread.Sleep(Yuck)在一段时间后重试删除目录。这个问题需要重新审视一个更现代的答案。.

public static async Task<bool> TryDeleteDirectory(
   string directoryPath,
   int maxRetries = 10,
   int millisecondsDelay = 30)
{
    if (directoryPath == null)
        throw new ArgumentNullException(directoryPath);
    if (maxRetries < 1)
        throw new ArgumentOutOfRangeException(nameof(maxRetries));
    if (millisecondsDelay < 1)
        throw new ArgumentOutOfRangeException(nameof(millisecondsDelay));

    for (int i = 0; i < maxRetries; ++i)
    {
        try
        {
            if (Directory.Exists(directoryPath))
            {
                Directory.Delete(directoryPath, true);
            }

            return true;
        }
        catch (IOException)
        {
            await Task.Delay(millisecondsDelay);
        }
        catch (UnauthorizedAccessException)
        {
            await Task.Delay(millisecondsDelay);
        }
    }

    return false;
}

单元测试

这些测试显示了锁定文件如何导致Directory.Delete失败以及上述TryDeleteDirectory方法如何解决问题的示例。.

[Fact]
public async Task TryDeleteDirectory_FileLocked_DirectoryNotDeletedReturnsFalse()
{
    var directoryPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
    var subDirectoryPath = Path.Combine(Path.GetTempPath(), "SubDirectory");
    var filePath = Path.Combine(directoryPath, "File.txt");

    try
    {
        Directory.CreateDirectory(directoryPath);
        Directory.CreateDirectory(subDirectoryPath);

        using (var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.Write))
        {
            var result = await TryDeleteDirectory(directoryPath, 3, 30);
            Assert.False(result);
            Assert.True(Directory.Exists(directoryPath));
        }
    }
    finally
    {
        if (Directory.Exists(directoryPath))
        {
            Directory.Delete(directoryPath, true);
        }
    }
}

[Fact]
public async Task TryDeleteDirectory_FileLockedThenReleased_DirectoryDeletedReturnsTrue()
{
    var directoryPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
    var subDirectoryPath = Path.Combine(Path.GetTempPath(), "SubDirectory");
    var filePath = Path.Combine(directoryPath, "File.txt");

    try
    {
        Directory.CreateDirectory(directoryPath);
        Directory.CreateDirectory(subDirectoryPath);

        Task<bool> task;
        using (var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.Write))
        {
            task = TryDeleteDirectory(directoryPath, 3, 30);
            await Task.Delay(30);
            Assert.True(Directory.Exists(directoryPath));
        }

        var result = await task;
        Assert.True(result);
        Assert.False(Directory.Exists(directoryPath));
    }
    finally
    {
        if (Directory.Exists(directoryPath))
        {
            Directory.Delete(directoryPath, true);
        }
    }
}
11
Muhammad Rehan Saeed

您可以通过运行以下方式重现错误:

Directory.CreateDirectory(@"C:\Temp\a\b\c\");
Process.Start(@"C:\Temp\a\b\c\");
Thread.Sleep(1000);
Directory.Delete(@"C:\Temp\a\b\c");
Directory.Delete(@"C:\Temp\a\b");
Directory.Delete(@"C:\Temp\a");

尝试删除目录'b'时,它会抛出IOException“目录不为空”。这是愚蠢的,因为我们刚刚删除了目录'c'。.

根据我的理解,解释是目录'c'被标记为已删除。但删除尚未在系统中提交。系统已完成作业的回复,而实际上它仍在处理中。系统可能正在等待文件资源管理器将焦点放在父目录上以提交删除。.

如果您查看删除功能的源代码( http://referencesource.Microsoft.com/#mscorlib/system/io/directory.cs ),您将看到它使用本机Win32Native.RemoveDirectory函数。这里记录了这种不等待的行为:

RemoveDirectory函数在关闭时标记要删除的目录。因此,在关闭目录的最后一个句柄之前,不会删除该目录。.

http://msdn.Microsoft.com/en-us/library/windows/desktop/aa365488(v=vs.85).aspx

睡眠和重试是解决方案。如果是ryascl的解决方案。.

10
Olivier de Rivoyre

我有一个奇怪的权限问题删除用户配置文件目录(在C:\ Documents and Settings中),尽管能够在Explorer Shell中这样做。.

File.SetAttributes(target_dir, FileAttributes.Normal);
Directory.Delete(target_dir, false);

对我来说对一个目录上的“文件”操作没有任何意义,但我知道它有效,这对我来说已经足够了!

7
Nick

这个答案基于: https://stackoverflow.com/a/1703799/184528 。与我的代码的不同之处在于,我们只会在必要时递归许多删除子目录和文件,第一次尝试时对Directory.Delete的调用失败(这可能因为Windows资源管理器查看目录而发生)。.

    public static void DeleteDirectory(string dir, bool secondAttempt = false)
    {
        // If this is a second try, we are going to manually 
        // delete the files and sub-directories. 
        if (secondAttempt)
        {
            // Interrupt the current thread to allow Explorer time to release a directory handle
            Thread.Sleep(0);

            // Delete any files in the directory 
            foreach (var f in Directory.GetFiles(dir, "*.*", SearchOption.TopDirectoryOnly))
                File.Delete(f);

            // Try manually recursing and deleting sub-directories 
            foreach (var d in Directory.GetDirectories(dir))
                DeleteDirectory(d);

            // Now we try to delete the current directory
            Directory.Delete(dir, false);
            return;
        }

        try
        {
            // First attempt: use the standard MSDN approach.
            // This will throw an exception a directory is open in Explorer
            Directory.Delete(dir, true);
        }
        catch (IOException)
        {
            // Try again to delete the directory manually recursing. 
            DeleteDirectory(dir, true);
        }
        catch (UnauthorizedAccessException)
        {
            // Try again to delete the directory manually recursing. 
            DeleteDirectory(dir, true);
        } 
    }
3
cdiggins

不删除文件的递归目录删除肯定是意外的。我对此的解决方法:

public class IOUtils
{
    public static void DeleteDirectory(string directory)
    {
        Directory.GetFiles(directory, "*", SearchOption.AllDirectories).ForEach(File.Delete);
        Directory.Delete(directory, true);
    }
}

我遇到过这种情况有帮助的情况,但一般来说,Directory.Delete会在递归删除时删除目录中的文件,如 在msdn 中记录。.

我不时会遇到这种不正常的行为,作为Windows资源管理器的用户:有时我无法删除文件夹(它认为无意义的消息是“访问被拒绝”)但是当我向下钻取并删除较低的项目时,我可以删除上层项目也是如此。所以我猜上面的代码处理操作系统异常 - 而不是基类库问题。.

2
citykid

我花了几个小时来解决这个问题以及删除目录的其他异常。这是我的解决方案

 public static void DeleteDirectory(string target_dir)
    {
        DeleteDirectoryFiles(target_dir);
        while (Directory.Exists(target_dir))
        {
            lock (_lock)
            {
                DeleteDirectoryDirs(target_dir);
            }
        }
    }

    private static void DeleteDirectoryDirs(string target_dir)
    {
        System.Threading.Thread.Sleep(100);

        if (Directory.Exists(target_dir))
        {

            string[] dirs = Directory.GetDirectories(target_dir);

            if (dirs.Length == 0)
                Directory.Delete(target_dir, false);
            else
                foreach (string dir in dirs)
                    DeleteDirectoryDirs(dir);
        }
    }

    private static void DeleteDirectoryFiles(string target_dir)
    {
        string[] files = Directory.GetFiles(target_dir);
        string[] dirs = Directory.GetDirectories(target_dir);

        foreach (string file in files)
        {
            File.SetAttributes(file, FileAttributes.Normal);
            File.Delete(file);
        }

        foreach (string dir in dirs)
        {
            DeleteDirectoryFiles(dir);
        }
    }

此代码具有较小的延迟,这对我的应用程序来说并不重要。但要小心,如果您要删除的目录中有很多子目录,则延迟可能会成为问题。.

2
Demid

以上解决方案对我来说效果不错。最后我使用了@ryascl解决方案的编辑版本,如下所示:

    /// <summary>
    /// Depth-first recursive delete, with handling for descendant 
    /// directories open in Windows Explorer.
    /// </summary>
    public static void DeleteDirectory(string path)
    {
        foreach (string directory in Directory.GetDirectories(path))
        {
            Thread.Sleep(1);
            DeleteDir(directory);
        }
        DeleteDir(path);
    }

    private static void DeleteDir(string dir)
    {
        try
        {
            Thread.Sleep(1);
            Directory.Delete(dir, true);
        }
        catch (IOException)
        {
            DeleteDir(dir);
        }
        catch (UnauthorizedAccessException)
        {
            DeleteDir(dir);
        }
    }
2
cahit beyaz

我今天遇到了这个问题。之所以发生这种情况,是因为我将Windows资源管理器打开到试图删除的目录,导致递归调用失败,从而导致IOException。确保没有对目录打开的句柄。.

此外,MSDN很清楚,你不必写自己的错觉: http://msdn.Microsoft.com/en-us/library/fxeahc5f.aspx

1
GrokSrc

看起来在Windows资源管理器中选择路径或子文件夹足以阻止Directory.Delete(path,true)的单次执行,如上所述抛出IOException并死亡,而不是将Windows资源管理器引导到父文件夹并作为预期。.

1
David Alpert

当路径长度大于260个符号的目录(或任何子目录)中存在文件时,此问题可能出现在Windows上。.

在这种情况下,您需要删除\\\\?\C:\mydir而不是C:\mydir。关于260个符号限制,您可以阅读 这里 。.

1
HostageBrain

我在使用TFS2012的构建服务器上的Windows Workflow Foundation遇到了同样的问题。在内部,名为Directory.Delete()的工作流将递归标志设置为true。在我们的案例中,它似乎与网络相关。.

我们正在删除网络共享上的二进制drop文件夹,然后重新创建并使用最新的二进制文件重新填充它。其他每个构建都会失败。在构建失败后打开drop文件夹时,该文件夹为空,这表示Directory.Delete()调用的每个方面都成功,除了删除实际目录。.

该问题似乎是由网络文件通信的异步性质引起的。构建服务器告诉文件服务器删除所有文件和文件服务器报告它已经有,即使它没有完全完成。然后构建服务器请求删除目录,文件服务器拒绝该请求,因为它尚未完全删除文件。.

在我们的案例中有两种可能的解

  • 在我们自己的代码中构建递归删除,并在每个步骤之间进行延迟和验证
  • 在IOException之后重试最多X次,在再次尝试之前给出延迟

后一种方法快速而肮脏,但似乎可以解决问题。.

1
Shaun

是否有可能存在竞争条件,其他线程或进程正在向目录添加文件:

顺序是:

删除过程A:

  1. 清空目录
  2. 删除(现在为空)目录。.

如果其他人在1和2之间添加了一个文件,那么可能2会抛出列出的异常?

1
Douglas Leeder

目录或其中的文件已锁定,无法删除。找到锁定它的罪魁祸首,看看你是否可以消除它。.

1
Vilx-

这是因为 FileChangesNotifications。

它发生在ASP.NET 2.0之后。当您删除应用程序中的某个文件夹时,它 重新启动 。您可以使用 ASP.NET运行状况监控 自己查看。.

只需将此代码添加到您的web.config/configuration/system.web:

<healthMonitoring enabled="true">
  <rules>
    <add name="MyAppLogEvents" eventName="Application Lifetime Events" provider="EventLogProvider" profile="Critical"/>
  </rules>
</healthMonitoring>


之后退房Windows Log -> Application。到底是怎么回事:

删除文件夹时,如果有任何子文件夹,Delete(path, true)会先删除子文件夹。 FileChangesMonitor足以了解删除和关闭您的应用程序。同时您的主目录尚未删除。这是来自Log的事件:


enter image description here


Delete()没有完成它的工作,因为app正在关闭,它引发了一个异常:

enter image description here

当您 没有任何子文件夹 在您要删除的文件夹中时,Delete()只删除所有文件和该文件夹,应用程序也会重新启动,但您 不会得到任何例外 ,因为app restart不会中断任何事情。但是,您仍然会丢失所有进程内会话,应用程序在重新启动时不响应请求等。.

现在怎么办?

有一些解决方法和调整来禁用这种行为, 目录连接关闭FCN与注册表使用反射停止FileChangesMonitor(因为没有暴露的方法) ,但他们都没有'似乎是正确的,因为FCN是有原因的。它正在照顾您的应用程序的结构,这不是您的数据的结构。简短的回答是:在应用程序之外放置要删除的文件夹。 FileChangesMonitor将不会收到任何通知,并且您的应用每次都不会重新启动。你不会有例外。要从网上看到它们,有两种方法:

  1. 创建一个处理传入呼叫的​​控制器,然后通过从应用程序外部的文件夹(wwwroot外部)读取文件。.

  2. 如果您的项目很大且性能最重要,请设置单独的小型和快速Web服务器来提供静态内容。因此,您将离开IIS他的具体工作。它可以在同一台机器上(用于Windows的mongoose)或另一台机器(用于Linux的nginx)。好消息是您无需支付额外的Microsoft许可证即可在Linux上设置静态内容服务器。.

希望这可以帮助。.

1
Roman

如上所述,“接受”的解决方案在重新分析点上失败了 - 但是人们仍然将它标记出来(???)。有一个更短的解决方案,可以正确复制功能:

public static void rmdir(string target, bool recursive)
{
    string tfilename = Path.GetDirectoryName(target) +
        (target.Contains(Path.DirectorySeparatorChar.ToString()) ? Path.DirectorySeparatorChar.ToString() : string.Empty) +
        Path.GetRandomFileName();
    Directory.Move(target, tfilename);
    Directory.Delete(tfilename, recursive);
}

我知道,不处理后面提到的权限情况,但是对于所有意图和目的,FAR BETTER提供 期望的功能 原始/库存Directory.Delete() - 并且代码也少得多 。.

你可以安全地进行处理,因为旧的目录将不在 ...即使没有消失,因为'文件系统仍在赶上'(或者MS为提供破坏的功能提供的任何借口) 。.

作为一个好处,如果你知道你的目标目录很大/很深并且不想等待(或者有异常),最后一行可以替换为:

    ThreadPool.QueueUserWorkItem((o) => { Directory.Delete(tfilename, recursive); });

你仍然可以安全地继续工作。.

1
Rob

我认为有一个文件打开了你不知道我有同样问题的流,并通过关闭所有指向我想要删除的目录的流来解决它。.

0
Ahmad Moussa

如果考虑使用任何文件或目录,则会发生此错误。这是一个误导性的错误。检查是否有任何资源管理器窗口或命令行窗口打开到树中的任何目录,或者是否在该树中使用文件的程序。.

0
allen1

在网络文件的情况下,Directory.DeleteHelper(recursive:= true)可能导致由于删除文件的延迟而导致的IOException

0
crowdy

如果您的应用程序(或任何其他应用程序)的当前目录是您尝试删除的目录,则它不会是访问冲突错误,但目录不为空。通过更改当前目录确保它不是您自己的应用程序;此外,请确保该目录未在某些其他程序中打开(例如Word,Excel,Total Commander等)。大多数程序将cd到最后打开的文件的目录,这将导致。.

0
configurator

当方法异步并且编码如下时,我解决了所述问题的一个可能实例:

// delete any existing update content folder for this update
if (await fileHelper.DirectoryExistsAsync(currentUpdateFolderPath))
       await fileHelper.DeleteDirectoryAsync(currentUpdateFolderPath);

有了这个:

bool exists = false;                
if (await fileHelper.DirectoryExistsAsync(currentUpdateFolderPath))
    exists = true;

// delete any existing update content folder for this update
if (exists)
    await fileHelper.DeleteDirectoryAsync(currentUpdateFolderPath);

结论?有一些异步的方面是摆脱用于检查微软无法说话的存在的句柄。就好像if语句中的异步方法的if语句就像using语句一样。.

0
Pat Pattillo

我已经用这种千年技术解决了(你可以将自己的Thread.Sleep留在catch中)

bool deleted = false;
        do
        {
            try
            {
                Directory.Delete(rutaFinal, true);                    
                deleted = true;
            }
            catch (Exception e)
            {
                string mensaje = e.Message;
                if( mensaje == "The directory is not empty.")
                Thread.Sleep(50);
            }
        } while (deleted == false);
0
Mauricio Rdz