【问题标题】:Delete non empty folder on reboot重启时删除非空文件夹
【发布时间】:2014-02-01 13:59:12
【问题描述】:

从域中删除用户后,我试图删除 Users 文件夹中的用户配置文件文件夹。问题是有时系统可能正在使用该文件夹。

问题是使用MOVEFILE_DELAY_UNTIL_REBOOTMoveFileEx 只会删除空文件夹。

From the MSDN:

如果 dwFlags 指定 MOVEFILE_DELAY_UNTIL_REBOOT 并且 lpNewFileNameNULL,则 MoveFileEx 注册 lpExistingFileName 系统重新启动时要删除的文件。如果 lpExistingFileName 引用了一个目录,则系统仅在目录为空时才会在重新启动时删除该目录。

删除其中包含正在使用的文件的非空文件夹的正确方法是什么?


这是一个基于 Michel 回答的简单测试程序,它按预期工作。

internal static class Program
{
    private static void Main(string[] args)
    {
        foreach (var file in Directory.EnumerateFiles(args[0], "*", SearchOption.AllDirectories))
        {
            Console.WriteLine(file);
        }

        foreach (var directory in Directory.EnumerateDirectories(args[0], "*", SearchOption.AllDirectories))
        {
            Console.WriteLine(directory);
            DeleteFileOnReboot(directory);
        }

        DeleteFileOnReboot(args[0]);
    }

    private static void DeleteFileOnReboot(string file)
    {
        bool result = MoveFileEx(file, null, MoveFileFlags.MOVEFILE_DELAY_UNTIL_REBOOT);
        try
        {
            if (!result)
                throw new Win32Exception();
        }
        catch (Win32Exception ex)
        {
            Console.WriteLine(ex);
        }
    }

    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    static extern bool MoveFileEx(string lpExistingFileName, string lpNewFileName, MoveFileFlags dwFlags);

}

[Flags]
enum MoveFileFlags
{
    MOVEFILE_REPLACE_EXISTING = 0x00000001,
    MOVEFILE_COPY_ALLOWED = 0x00000002,
    MOVEFILE_DELAY_UNTIL_REBOOT = 0x00000004,
    MOVEFILE_WRITE_THROUGH = 0x00000008,
    MOVEFILE_CREATE_HARDLINK = 0x00000010,
    MOVEFILE_FAIL_IF_NOT_TRACKABLE = 0x00000020
}

我使用Directory.EnumerateFilesDirectory.EnumerateDirectories 在两个循环中执行此操作,因为Directory.EnumerateFileSystemEntries 将在文件夹中的文件之前列出文件夹,因此删除会失败。

【问题讨论】:

    标签: c# winapi movefileex


    【解决方案1】:

    在我见过的大多数实现中,目录中的每个文件都用MoveFileExMOVEFILE_DELAY_UNTIL_REBOOT“删除”,然后以同样的方式“删除”目录。重新启动时会保留操作顺序 - 首先删除文件,然后删除目录。

    【讨论】:

      【解决方案2】:

      我同意 Michael Gunter 的回答。刚刚添加了 Michael 建议的代码示例。

      public class Cleanuper
      {
          private void PendingDeleteDirectory(string directoryPath)
          {
              foreach (string directory in Directory.GetDirectories(directoryPath, "*", SearchOption.TopDirectoryOnly))
              {
                  PendingDeleteDirectory(directory);
              }
      
              foreach (string file in Directory.GetFiles(directoryPath, "*", SearchOption.TopDirectoryOnly))
              {
                  NativeMethods.MoveFileEx(file, null, MoveFileFlags.DelayUntilReboot);
              }
              NativeMethods.MoveFileEx(directoryPath, null, MoveFileFlags.DelayUntilReboot);
          }
      }
      
      public static class NativeMethods
      {
          [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
          internal static extern bool MoveFileEx(string lpExistingFileName, string lpNewFileName, MoveFileFlags dwFlags);
      }
      
      [Flags]
      public enum MoveFileFlags
      {
          DelayUntilReboot = 0x00000004
      }
      

      【讨论】:

        猜你喜欢
        • 2010-09-23
        • 1970-01-01
        • 2017-02-19
        • 2012-06-18
        • 1970-01-01
        • 2020-07-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多