如何删除由 ReadDirectoryChangesW 监视的子项的父项
How to delete parent of child being monitored by ReadDirectoryChangesW
使用 ReadDirectoryChangesW 监视文件夹会导致其父文件夹被锁定且无法删除。
这里有一篇关于这个的帖子:
查找第一个更改通知锁定父文件夹
但其中提到的唯一解决方案是,我们应该始终在顶层倾听。
有没有人找到更好的方法来做到这一点,而不是在顶级观看?
有时,这可以一直到观看驱动器,并且不会在机器上花费大量处理时间。
谢谢!
文件夹只有在为空的情况下才能删除,否则我们得到错误STATUS_DIRECTORY_NOT_EMPTY
-指示尝试删除的目录不为空。
从另一侧 - 如果您有文件的打开句柄 - 在您不关闭它句柄之前无法删除它(此处更改的内容从 Win10 RS1 开始(
因此,如果您使用ReadDirectoryChangesW
监视某个子子文件夹,则在未关闭此句柄之前,无法(在WIN10_RS1之前(删除父文件夹。
在一般过程中看起来像 - 当有人尝试删除文件夹时 - 它必须枚举其中的所有文件(子文件夹(并首先删除它。 当对调用ReadDirectoryChangesW
文件夹应用删除操作时 - IO 请求将以状态STATUS_DELETE_PENDING
完成 -已请求对删除挂起的文件对象执行非关闭操作。 (它转换为Win32错误代码ERROR_ACCESS_DENIED
-访问被拒绝。).从ReadDirectoryChangesW
收到此错误时,必须关闭此调用中使用的目录句柄。然后是提高 - 谁是第一个 - 你关闭目录句柄或其他代码尝试删除父文件夹...
从 win10 RS1 开始,可能删除父文件,即使有人通过调用NtSetInformationFile
FileDispositionInformationEx
或SetFileInformationByHandle
FileDispositionInfoEx
来打开它的子文件(文件夹(。
新标志FILE_DISPOSITION_POSIX_SEMANTICS
中的魔力(指定系统应执行 POSIX 样式的删除(
通常,标记为删除的文件实际上不会被删除,直到所有 文件的打开句柄已关闭,并且 文件为零。使用 标记要删除的文件时
FILE_DISPOSITION_POSIX_SEMANTICS
,链接将从 一旦 POSIX 删除句柄关闭,可见命名空间, 但该文件的数据流仍可由其他现有数据流访问 句柄,直到最后一个句柄关闭。
因此,当我们使用它时 - 文件本身当然不会被删除,直到ReadDirectoryChangesW
调用者不关闭自句柄,但文件将从父文件夹中删除。 结果,父文件夹可以变为空,之后我们可以将其删除。
请注意,这里的DeleteFileW
和RemoveDirectoryW
在这里不起作用,因为他们使用旧的信息类FileDispositionInformation与FILE_DISPOSITION_INFORMATION
ULONG DeletePosix(PCWSTR lpFileName)
{
HANDLE hFile = CreateFileW(lpFileName, DELETE, FILE_SHARE_VALID_FLAGS, 0, OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OPEN_REPARSE_POINT, 0);
if (hFile == INVALID_HANDLE_VALUE)
{
return GetLastError();
}
static FILE_DISPOSITION_INFO_EX fdi = { FILE_DISPOSITION_DELETE| FILE_DISPOSITION_POSIX_SEMANTICS };
ULONG dwError = SetFileInformationByHandle(hFile, FileDispositionInfoEx, &fdi, sizeof(fdi))
? NOERROR : GetLastError();
// win10 rs1: file removed from parent folder here
CloseHandle(hFile);
return dwError;
}
当然,孩子必须在其他调用中打开FILE_SHARE_DELETE
,否则我们以后根本无法用DELETE
访问打开它
指定获取目录句柄时要CreateFile()
的正确属性非常重要。试试这个:
HANDLE hDir = ::CreateFile(
strDirectoryName,
FILE_LIST_DIRECTORY,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL, // security descriptor
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
NULL);
为共享模式指定FILE_SHARE_DELETE
也很重要。
- 正在VS调试器中监视映射条目
- 在程序运行时监视 VxWorks 中的任务 CPU 利用率
- 如何删除由 ReadDirectoryChangesW 监视的子项的父项
- 是否有一个标准函数可以打印/监视stdin文件的内容,同时将数据留在stdin中
- 监视GNU Radio中的缓冲区
- 监视 SDK 下的未定义符号"__Unwind_SjLj_Unregister"
- C++使用条件变量监视类/包装器
- C++ 使用读取目录更改监视文件更改W不触发所有操作?
- 如何:监视Windows中另一个进程的文件访问?
- 如何监视应用程序进行的Windows系统API调用?
- 如何在Linux中监视子过程状态
- C++中在Visual Studio的"监视"窗口中平展继承的成员?
- 应用程序如何检测缩放和监视Windows 10上的布局更改
- 是否可以使用 select(2) 来监视 SDL 文本输入事件
- 如何监视Windows USB端口上的输入
- C 向CMD.EXE监视命令注入DLL
- Visual Studio监视窗口如何知道展开"std::vector<T>"并显示元素?
- 监视OpenCL内核中的进度
- C++监视操作系统事件并中断它们
- 使用win32监视Windows任务栏状态更改