(Обновлено с более простым кодом)
Я использую 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 никогда не просыпается.
Почему создание каталога вызывает уведомление для двух папок вверх? Почему не только родитель? Почему создание файла и папки должны действовать по-другому?
Задача ещё не решена.
Других решений пока нет …