C++ 如何删除ReadDirectoryChangesW监视的子级的父级
使用ReadDirectoryChangesW监视文件夹会导致其父文件夹被锁定且无法删除 这里有一篇关于这个的帖子: 但其中提到的唯一解决办法是,我们应该始终听取高层的意见 有没有人找到了一个更好的方法来做这件事,而不是在高层观看 有时,这会一直持续到观看驱动器,而这不会在机器上花费太多的处理时间C++ 如何删除ReadDirectoryChangesW监视的子级的父级,c++,winapi,visual-c++,readdirectorychangesw,change-notification,C++,Winapi,Visual C++,Readdirectorychangesw,Change Notification,使用ReadDirectoryChangesW监视文件夹会导致其父文件夹被锁定且无法删除 这里有一篇关于这个的帖子: 但其中提到的唯一解决办法是,我们应该始终听取高层的意见 有没有人找到了一个更好的方法来做这件事,而不是在高层观看 有时,这会一直持续到观看驱动器,而这不会在机器上花费太多的处理时间 谢谢 获取目录句柄时,为CreateFile()指定正确的属性非常重要。试试这个: HANDLE hDir = ::CreateFile( strDirectoryName, FIL
谢谢 获取目录句柄时,为
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);
为共享模式指定
文件\u共享\u删除
也很重要。文件夹只有在为空的情况下才能删除,否则我们得到错误状态\u目录\u非空
-表示尝试删除的目录不是空的
另一方面,如果您有文件的打开句柄,则在未关闭句柄之前,无法删除该文件(此处更改的内容从win10 rs1开始)
因此,如果使用ReadDirectoryChangesW
监视某个子文件夹,则已打开该子文件夹的句柄,并且在未关闭该句柄之前,无法删除父文件夹(在WIN10\u RS1之前)
一般情况下,当有人尝试删除文件夹时,它必须枚举其中的所有文件(子文件夹),然后首先删除它。当对调用了ReadDirectoryChangesW
的文件夹应用删除操作时-io请求将以状态status\u delete\u PENDING
完成-已请求对具有删除挂起的文件对象执行非关闭操作。(它转换为win32错误代码错误\u访问被拒绝
-访问被拒绝。)。当您从ReadDirectoryChangesW
收到此错误时,必须关闭此调用中使用的目录句柄。然后是raise-谁是第一个-您关闭目录句柄或其他代码尝试删除父文件夹
从win10 rs1开始可能删除父文件,即使有人通过使用或调用来保持子文件(文件夹)的打开句柄 新标志
文件\u处置\u POSIX\u语义中的魔力(指定系统应执行POSIX样式的删除)
通常,标记为删除的文件在所有
文件的打开句柄已关闭,并且
文件为零。使用将文件标记为删除时
FILE\u DISPOSITION\u POSIX\u SEMANTICS
,该链接将从
一旦POSIX删除句柄关闭,名称空间就可见,
但该文件的数据流仍然可以被其他现有用户访问
直到最后一个句柄关闭为止
所以,当我们使用这个-文件本身当然不会被删除,直到调用ReadDirectoryChangesW
notcloselfhandle,但文件将从父文件夹中删除。因此,父文件夹可以变为空,之后我们可以将其删除
请注意,这里的DeleteFileW
和RemoveDirectoryW
将不起作用,因为它们使用了旧的信息类
当然,在其他调用中,child必须使用FILE\u SHARE\u DELETE
打开,否则我们以后就不能使用DELETE
访问打开它
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;
}