Почему ReadDirectoryChangesW не запускается правильно, когда подкаталог создается в наблюдаемом каталоге?

(Обновлено с более простым кодом)

Я использую ReadDirectoryChangesW (), чтобы отслеживать изменения в определенных папках. Это работает правильно, когда файл создается в одной из просматриваемых папок, но когда подкаталог создан он никогда не уведомляется.

Например, если я смотрю путь c: \ testA \ testB и создаю файл в этой папке, то ReadDirectoryChangesW () работает правильно. Если я вместо этого создаю каталог в этой папке WaitForSingleObjectEx никогда не вернется.

Интересно, что если я вместо этого наблюдаю за c: \ testA и создаю каталог в каталоге c: \ testA \ testB, тогда WaitForSingleObjectEx возвращается, как и ожидалось. Обратите внимание, что я не смотрю подпапки (bWatchSubtree == false), поэтому этот результат очень странный.

Одним из возможных решений является просмотр двух папок для каждой папки, которую я хочу отслеживать, самой папки для изменений файлов и родительской папки для любых изменений подкаталогов, но вы можете понять, почему это утомительно.

Вот пример кода для воспроизведения проблемы:

HANDLE watchDir(const char* dirPath)
{
HANDLE dir = CreateFile(
dirPath,
FILE_LIST_DIRECTORY,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
NULL);

const size_t kBufferSize = 32 * 1024;
char buffer[kBufferSize];
OVERLAPPED overlap;

memset(&overlap, 0, sizeof(overlap));
memset(&buffer, 0, sizeof(buffer));

overlap.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

if (ReadDirectoryChangesW(
dir,
buffer,
sizeof(buffer),
FALSE,  /* bWatchSubtree = false, we only watch one folder*/
FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_CREATION,
NULL,
&overlap,
NULL) != 0)
{
return overlap.hEvent;
}
else
{
return nullptr;
}
}

void main(int nargs, const char* args)
{
HANDLE watchHandle = watchDir("C:\\testA\\testB");
if (watchHandle == nullptr)
{
cout << "Failed to issue watch command" << endl;
return;
}

DWORD result = WaitForSingleObjectEx(watchHandle, INFINITE, false);

// This code will never be reached when creating a dir in c:\testA\testB, but it WILL if a file is created in that folder.
cout << "Done waiting for dir: " << result << endl;
}

Запуск этого кода и создание нового файл в c: \ testA \ testB \ newfile.txt выдает этот вывод:

c:\testA\testB modified.

Запуск этого кода и создание нового каталог в c: \ testA \ testB \ newdir никогда не просыпается.

Почему создание каталога вызывает уведомление для двух папок вверх? Почему не только родитель? Почему создание файла и папки должны действовать по-другому?

0

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]