gpt4 book ai didi

c++ - 如何删除 ReadDirectoryChangesW 监视的子项的父项

转载 作者:行者123 更新时间:2023-11-28 04:34:26 35 4
gpt4 key购买 nike

使用 ReadDirectoryChangesW 监视文件夹会导致其父级被锁定且无法删除。

这里有一篇关于这个的帖子:

FindFirstChangeNotification locks parent folder

但其中提到的唯一解决方案是我们应该始终在顶层倾听。

有没有人找到比在顶层观看更好的方法来做到这一点?

有时,这可以一直到观看驱动器,并且不会在机器上花费很多处理时间。

谢谢!

最佳答案

文件夹只有在它为空的情况下才能被删除,否则我们会得到错误 STATUS_DIRECTORY_NOT_EMPTY - 表明试图删除的目录不为空。

从另一方面来说 - 如果您有文件的打开句柄 - 在您不关闭它句柄之前无法删除它(这里的某些更改从 win10 rs1 开始)

因此,如果您使用 ReadDirectoryChangesW 监视某个子文件夹,您已经打开了它的句柄,并且父文件夹不能(在 WIN10_RS1 之前)被删除,直到您不关闭它处理。

一般过程看起来像 - 当有人尝试删除文件夹时 - 它必须枚举其中的所有文件(子文件夹)并首先删除它。当删除操作应用于调用了 ReadDirectoryChangesW 的文件夹时 - io 请求将以状态 STATUS_DELETE_PENDING 完成 - 已请求文件的非关闭操作具有删除挂起的对象。(它转换为 win32 错误代码 ERROR_ACCESS_DENIED - 访问被拒绝。)。当您从 ReadDirectoryChangesW 收到此错误时,您必须关闭此调用中使用的目录句柄。然后是 raise - 谁是第一个 - 你关闭目录句柄或另一个代码尝试删除父文件夹......


从 win10 rs1 开始可能会删除父级,即使有人通过调用 NtSetInformationFile 持有它的子文件(文件夹)的打开句柄|与 FileDispositionInformationExSetFileInformationByHandleFileDispositionInfoEx .

新标志 FILE_DISPOSITION_POSIX_SEMANTICS 的神奇之处(指定系统应执行 POSIX 风格的删除)

Normally a file marked for deletion is not actually deleted until all open handles for the file have been closed and the link count for the file is zero. When marking a file for deletion using FILE_DISPOSITION_POSIX_SEMANTICS, the link gets removed from the visible namespace as soon as the POSIX delete handle has been closed, but the file’s data streams remain accessible by other existing handles until the last handle has been closed.

所以当我们使用这个时 - 文件本身当然不会被删除,直到 ReadDirectoryChangesW 的调用者不关闭自身句柄,但文件将从父文件夹中删除。结果父文件夹可能变空,之后我们可以删除它。

注意 DeleteFileWRemoveDirectoryW 在这里不起作用,因为它们使用了旧的信息类 FileDispositionInformationFILE_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;
}

当然 child 必须在其他调用中用 FILE_SHARE_DELETE 打开,否则我们以后根本无法用 DELETE 访问打开它

关于c++ - 如何删除 ReadDirectoryChangesW 监视的子项的父项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51902554/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com