Я пытаюсь отслеживать изменения файлов, но я не совсем уверен, как прочитать имя файла в структуре FILE_NOTIFY_INFORMATION:
HANDLE dwChangeHandles[2];
DWORD dwWaitStatus;
wChangeHandles[0] = FindFirstChangeNotification(dirname.c_str(), FALSE, FILE_NOTIFY_CHANGE_LAST_WRITE);
if (dwChangeHandles[0] == INVALID_HANDLE_VALUE) printerr(__FILE__,__LINE__,"FindFirstChangeNotification function failed.\n");
...
if ((dwChangeHandles[0] == NULL) || (dwChangeHandles[1] == NULL)) //final validation
printerr(__FILE__,__LINE__,"Unexpected NULL from FindFirstChangeNotification.\n");
while (TRUE) {
std::cout << "Waiting for notification...\n";
dwWaitStatus = WaitForMultipleObjects(2, dwChangeHandles, FALSE, INFINITE);
if(dwWaitStatus==WAIT_OBJECT_0){
std::cout << "Something changed\n";
DWORD BytesReturned;
size_t bufLen = 1024;
FILE_NOTIFY_INFORMATION buffer[bufLen];
if (ReadDirectoryChangesW(dwChangeHandles[0], buffer, bufLen, FALSE, FILE_NOTIFY_CHANGE_LAST_WRITE, &BytesReturned, NULL, NULL)){
std::wcout << std::wstring(buffer->FileName)<< std::endl; //THERE IS NOTHING IN THE EXPECTED OUTPUT HERE
}
if (FindNextChangeNotification(dwChangeHandles[0]) == FALSE ) printerr(__FILE__,__LINE__,"FindNextChangeNotification function failed.\n");
}
else if(dwWaitStatus==WAIT_TIMEOUT) printerr(__FILE__,__LINE__,"No changes in the timeout period.\n");
else printerr(__FILE__,__LINE__,"Unhandled dwWaitStatus.\n");
}
Есть ли что-то, что я делаю не так
У вас есть ряд проблем, которые я вижу сразу:
Согласно документам для ReadDirectoryChangesW
функция, буфер должен быть DWORD
-aligned. Поскольку вы используете буфер в стеке, это не гарантируется — вместо этого вы должны выделить его из кучи.
Вы, кажется, не используете функцию правильно. Обычно вы бы позвонили ReadDirectoryChangesW
во-первых, и затем ждать на мероприятии. А не наоборот. когда ReadDirectoryChangesW
возвращает для асинхронного вызова, в этой точке обычно нет данных в буфере. Вам нужно дождаться уведомления о том, что запрос был выполнен, прежде чем использовать содержимое буфера.
FindNextChangeNotification
используется только с FindFirstChangeNotification
так что это совершенно неправильно. Когда ReadDirectoryChangesW
завершает вам нужно использовать NextEntryOffset
поле в FILE_NOTIFY_INFORMATION
структура, чтобы пройти через возвращенные события.
редактировать: Так как вы добавили больше кода к своему вопросу, теперь очевидно, что вы смешиваете два API. FindFirstChangeNotification
а также FindNextChangeNotification
один API, и ReadDirectoryChangesW
Другой. Я полагаю, что вы были смущены этим отрывком из документации:
Эта функция не указывает на изменение, которое удовлетворило ожидание
состояние. Чтобы получить информацию о конкретном изменении как часть
уведомления, используйте функцию ReadDirectoryChangesW.
Полагаю, ваша путаница понятна, но два API нельзя использовать вместе. Если вы используете FindFirstChangeNotification
тогда все, что вы получите, это уведомление о том, что что-то изменилось, и вы должны перечитать каталог, чтобы узнать, что это было. Если вы хотите конкретные уведомления на уровне файлов, то вы должны использовать ReadDirectoryChangesW
сделать мониторинг.