Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何删除ReadDirectoryChangesW监视的子级的父级_C++_Winapi_Visual C++_Readdirectorychangesw_Change Notification - Fatal编程技术网

C++ 如何删除ReadDirectoryChangesW监视的子级的父级

C++ 如何删除ReadDirectoryChangesW监视的子级的父级,c++,winapi,visual-c++,readdirectorychangesw,change-notification,C++,Winapi,Visual C++,Readdirectorychangesw,Change Notification,使用ReadDirectoryChangesW监视文件夹会导致其父文件夹被锁定且无法删除 这里有一篇关于这个的帖子: 但其中提到的唯一解决办法是,我们应该始终听取高层的意见 有没有人找到了一个更好的方法来做这件事,而不是在高层观看 有时,这会一直持续到观看驱动器,而这不会在机器上花费太多的处理时间 谢谢 获取目录句柄时,为CreateFile()指定正确的属性非常重要。试试这个: HANDLE hDir = ::CreateFile( strDirectoryName, FIL

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

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

但其中提到的唯一解决办法是,我们应该始终听取高层的意见

有没有人找到了一个更好的方法来做这件事,而不是在高层观看

有时,这会一直持续到观看驱动器,而这不会在机器上花费太多的处理时间


谢谢

获取目录句柄时,为
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;
}