0

Я пытаюсь отслеживать изменения файлов, но я не совсем уверен, как читать имя файла в FILE_NOTIFY_INFORMATION структуры:Как я должен прочитать имя файла в 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"); 
    } 

Есть ли что-то, что я делаю неправильно

ответ

2

у вас есть целый ряд проблем, которые я вижу сразу:

  1. Согласно документации для функции ReadDirectoryChangesW, буфер необходимости s должно быть DWORD -определено. Поскольку вы используете буфер в стеке, это не гарантируется - вместо этого вы должны выделить один из кучи.

  2. Вы, кажется, не используете функцию правильно. Обычно вы сначала вызываете ReadDirectoryChangesW, а затем wait on the event. А не наоборот. Когда ReadDirectoryChangesW возвращается для асинхронного вызова, в буфере в этой точке обычно нет данных. Вам нужно дождаться уведомления о том, что запрос был выполнен до использования содержимого буфера.

  3. FindNextChangeNotification используется только с FindFirstChangeNotification, так что это совершенно неправильно. Когда заканчивается ReadDirectoryChangesW, вам необходимо использовать поле NextEntryOffset в структуре FILE_NOTIFY_INFORMATION для циклического прохождения возвращаемых событий.

Edit: Поскольку вы добавили больше коды на ваш вопрос, что теперь очевидно, что вы смешиваете два API. FindFirstChangeNotification и FindNextChangeNotification - один API, а ReadDirectoryChangesW - другой. Я считаю, что вы были смущены этим отрывком в документации:

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

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

+0

Ну, я использовал дескриптор, возвращаемый FindFirstChangeNotification, так как я где-то читал, что он действителен для конкретной информации о событии, используя ReadDirectoryChangesW – shuji

+0

@shuji Нет, эти две функции совершенно разные. Ручка, которую вы даете 'ReadDirectoryChangesW', должна поступать из' CreateFile'. –

+0

Да, я просто попробовал это и отлично работал, спасибо, брат. – shuji