C++ ReadDirectoryChangesW不捕获复制或创建文件时添加的文件\u操作\u

C++ ReadDirectoryChangesW不捕获复制或创建文件时添加的文件\u操作\u,c++,c,windows,file-monitoring,C++,C,Windows,File Monitoring,我正在尝试使用ReadDirectoryChangesW跟踪文件的创建、复制或移动到受监控目录的时间 我的问题是,当我在受监视的目录上复制或创建文件时,ReadDirectoryChangesW没有捕获任何文件\u操作\u添加的事件,而只捕获文件\u操作\u修改的事件 另一方面,当我移动一个文件而不是从另一个目录复制或创建到受监视的目录时,就会捕获添加的文件 我想知道是否有人知道在我的3个案例中添加ReadDirectoryChangesW捕获文件的方法:创建、复制和移动 我这样称呼ReadDi

我正在尝试使用ReadDirectoryChangesW跟踪文件的创建、复制或移动到受监控目录的时间

我的问题是,当我在受监视的目录上复制或创建文件时,ReadDirectoryChangesW没有捕获任何文件\u操作\u添加的事件,而只捕获文件\u操作\u修改的事件

另一方面,当我移动一个文件而不是从另一个目录复制或创建到受监视的目录时,就会捕获添加的文件

我想知道是否有人知道在我的3个案例中添加ReadDirectoryChangesW捕获文件的方法:创建、复制和移动

我这样称呼ReadDirectoryChangesW:

ReadDirectoryChangesW(directory_handle, buffer, MAX_EVENTs_BUFFER,
    FALSE, FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME |
    FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_SIZE,
    NULL, (LPOVERLAPPED)usr_data, FileIOCompletionRoutine)
我使用CreateFileA初始化目录句柄:

然后,在我的FileIOCompletionRoutine中,当我将文件复制到受监控的目录时,或者当我创建文件时,我从未收到添加的文件\u操作\u,只有当我移动文件时。这是正常行为还是我做错了什么

编辑1:

VOID CALLBACK FileIOCompletionRoutine(_In_ DWORD err, _In_ DWORD bytes, _Inout_ LPOVERLAPPED lpOverlapped)
{
    CUSTOM_OVERLAPPED* pCustomOverlapped = (CUSTOM_OVERLAPPED*)lpOverlapped;
    char* buffer_offset = (char*)pCustomOverlapped->buffer;
    PFILE_NOTIFY_INFORMATION pInfo = (PFILE_NOTIFY_INFORMATION)buffer_offset;

    do
    {        
        pInfo = (PFILE_NOTIFY_INFORMATION)buffer_offset;
        switch (pInfo->Action)
        {
            case FILE_ACTION_ADDED:
            {              
                std::cout << "file added!\n";
                break;
            }
            case FILE_ACTION_MODIFIED:
            {
                std::cout << "file modified!\n";
                break;
            }
            // and so on...
        }
        buffer_offset += pInfo->NextEntryOffset;        
    } while(pInfo->NextEntryOffset);
}
编辑2:

我发现,如果我从ReadDirectoryChangesW中删除文件\u NOTIFY\u CHANGE\u LAST\u WRITE,则在创建新文件和执行剪切粘贴时,文件\u ACTION\u ADDED事件会被正确捕获,但在执行复制粘贴时则不会,在这种情况下,它会触发文件\u ACTION\u MODIFIED。为了在复制并粘贴到受监视目录时添加文件操作,我还需要删除文件通知更改大小标志

因此,通过这种方式,如果要跟踪在受监控目录中创建、复制或移动的新文件,我只需要ReadDirectoryChangesW函数上的标志FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME。 如果我想跟踪目录文件中已经存在的修改,我需要文件大小,但我不能使用ReadDirectoryChangesW上的三个标志中的或来跟踪新文件和修改的文件

你们中有人找到了用三个标志中的逻辑“或”来跟踪所有这些事件的方法吗?或者我必须为每种情况调用不同标志的ReadDirectoryChangesW吗?

事实上,ReadDirectoryChangesW返回一个可以包含多个文件信息结构的缓冲区。第一个是缓冲区开头的预期值,但如果字段NextEntryOffset不是null,则它是下一个结构的char缓冲区中的偏移量

因此,您的回调应该是:

VOID CALLBACK FileIOCompletionRoutine(_In_ DWORD err, _In_ DWORD bytes, _Inout_ LPOVERLAPPED lpOverlapped)
{
    CUSTOM_OVERLAPPED* pCustomOverlapped = (CUSTOM_OVERLAPPED*)lpOverlapped;
    char* buffer_offset = (char*)pCustomOverlapped->buffer;
    PFILE_NOTIFY_INFORMATION pInfo = (PFILE_NOTIFY_INFORMATION)buffer_offset;

    do {
        switch (pInfo->Action)
        {
            case FILE_ACTION_ADDED:
            {              
                std::cout << "file added!\n";
                break;
            }
            case FILE_ACTION_MODIFIED:
            {
                std::cout << "file modified!\n";
                break;
            }
            // and so on...
        }
        pInfo = (PFILE_NOTIFY_INFORMATION)(buffer_offset + pInfo->NextEntryOffset);
    } while (0 != pInfo->NextEntryOffset);
}

嗨@Serge我在循环时已经在做了,我没有正确复制代码片段,对不起。我刚刚编辑了这个问题。问题是,当我在受监视的目录上创建一个新文件时,我得到了两个file\u ACTION\u MODIFIED事件,但没有添加任何file\u ACTION\u。复制文件时也会发生同样的情况。
VOID CALLBACK FileIOCompletionRoutine(_In_ DWORD err, _In_ DWORD bytes, _Inout_ LPOVERLAPPED lpOverlapped)
{
    CUSTOM_OVERLAPPED* pCustomOverlapped = (CUSTOM_OVERLAPPED*)lpOverlapped;
    char* buffer_offset = (char*)pCustomOverlapped->buffer;
    PFILE_NOTIFY_INFORMATION pInfo = (PFILE_NOTIFY_INFORMATION)buffer_offset;

    do {
        switch (pInfo->Action)
        {
            case FILE_ACTION_ADDED:
            {              
                std::cout << "file added!\n";
                break;
            }
            case FILE_ACTION_MODIFIED:
            {
                std::cout << "file modified!\n";
                break;
            }
            // and so on...
        }
        pInfo = (PFILE_NOTIFY_INFORMATION)(buffer_offset + pInfo->NextEntryOffset);
    } while (0 != pInfo->NextEntryOffset);
}