Reputation: 1839
I want to watch for changes done with a file (the event i'm waiting for is change contents event, i.e. last modified date is updated)
I have a code like this (minimalized example of actual code)
I expect that each iteration of the while loop the event gets reset and is available to be fired again but that doesn't happen
Why it fires change event only once?
int main()
{
const wchar_t *dir_path = L"C:\\Users\\IC\\AppData\\Roaming\\JetBrains\\CLion2021.3\\scratches\\";
HANDLE hDir = ::CreateFileW(
dir_path,
FILE_LIST_DIRECTORY,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
NULL
);
FILE_NOTIFY_INFORMATION fni;
OVERLAPPED overlapped;
overlapped.hEvent = ::CreateEventA(NULL, FALSE, FALSE, NULL);
::ReadDirectoryChangesW(
hDir,
&fni,
sizeof(fni),
TRUE,
FILE_NOTIFY_CHANGE_LAST_WRITE,
NULL,
&overlapped,
NULL
);
while (true)
{
std::vector<HANDLE> all_job_event_handles;
if (::ResetEvent(overlapped.hEvent) == FALSE)
{
printf("ResetEvent failed\n");
fflush(stdout);
return 1;
}
all_job_event_handles.push_back(overlapped.hEvent);
DWORD result = ::WaitForMultipleObjects(all_job_event_handles.size(), all_job_event_handles.data(), FALSE, INFINITE);
if (result == WAIT_FAILED)
{
printf("WaitForMultipleObjects failed\n");
fflush(stdout);
return 1;
}
if (result >= WAIT_OBJECT_0 && result < WAIT_OBJECT_0 + all_job_event_handles.size())
{
printf("file changed\n");
fflush(stdout);
}
}
}
Upvotes: 0
Views: 184
Reputation: 72054
Because that's just not how ReadDirectoryChanges
works. It doesn't continuously send you changes. It sends you one batch of changes. You process them. You call the function again to tell the system that you want more changes.
I found a correct usage example of the function here: https://gist.github.com/nickav/a57009d4fcc3b527ed0f5c9cf30618f8
Some side notes:
ReadDirectoryChanges
succeeds. This is bad; if it failed, you will hang on the Wait call forever.OVERLAPPED
structure.FALSE
). ResetEvent
on such an event does nothing.WaitForMultipleObjects
. This does nothing at best, but will eventually fail because WFMO
doesn't allow more than MAXIMUM_WAIT_OBJECTS
handles, and this number is fairly low (32, I think).Upvotes: 1