Multiple Files with ReadDirectoryChangesW
Apologies for starting another thread on this function (and posting it in this thread, should've really gone in the Visual C++ thread...) but I'm having a problem picking up multiple files copied to a watched directory.
I have a watched directory which is picking up single files perfectly fine. However, when I drop 2 or more files into the directory, I am only able to pick up the 1st file.
My current code is as follows:
HTML Code:
UINT CMyAppDlg::ReadDirChangesThread(LPVOID lpData)
{
AFX_MANAGE_STATE(AfxGetModuleState());
USES_CONVERSION;
OutputThreadDebug("Directory Changes Thread Started...");
CString csFilename = "";
ThreadData *pData = (ThreadData*) lpData;
HANDLE hDir = ::CreateFile(pData->csDirectory, FILE_LIST_DIRECTORY, FILE_SHARE_READ|FILE_SHARE_DELETE|FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS,
NULL);
ASSERT(hDir != INVALID_HANDLE_VALUE);
FILE_NOTIFY_INFORMATION Buffer[512];
memset((void*)&Buffer,0,sizeof(Buffer));
DWORD dwBytesReturned;
BOOL bFound = FALSE;
do
{
if (ReadDirectoryChangesW(hDir,&Buffer,
sizeof(Buffer),
FALSE,
FILE_NOTIFY_CHANGE_FILE_NAME,
&dwBytesReturned,
NULL,
NULL))
{
csFilename = (CString(Buffer[0].FileName).Left(Buffer[0].FileNameLength / 2));
// Do something with the filename
}
// Post a message to the calling thread indicating that we've finished
::PostMessage(pData->ParenthWnd,UWM_THREAD_FINSHED,0,0);
::OutputDebugString("Thread finished\n");
}
I know this will only ever pick up one filename, but I was hoping there would be a nice easy way to modify this to pick up multiple filenames and add them to thread safe array maybe?
Or would it be easier to run this in asynchronous mode? Or am I doing this compeltely wrong?!
Re: Multiple Files with ReadDirectoryChangesW
take a look at the Fwatch sample in the MSDN.
http://msdn.microsoft.com/library/de...hangeswapi.asp
Cheers
Re: Multiple Files with ReadDirectoryChangesW
Looks okay to me, but the buffer used by ReadDirectoryChangesW may hold more than one filename, so you must loop through the buffer until there are no more entries to process. Use the NextEntryOffset member to determine where the next entry begins.
Here's an example:
Code:
TCHAR szBuffer[640] = {0};
DWORD dwOffset = 0;
FILE_NOTIFY_INFORMATION* pInfo = NULL;
ReadDirectoryChangesW(hDrive, szBuffer, ARRAYSIZE(szBuffer), TRUE, FILE_NOTIFY_CHANGE_DIR_NAME, &dwBytes, NULL, NULL);
// A change has occurred within this directory structure. Process the change...
do
{
pInfo = (FILE_NOTIFY_INFORMATION*) &szBuffer[dwOffset];
switch (pInfo->Action)
{
case FILE_ACTION_ADDED:
break;
case FILE_ACTION_REMOVED:
break;
case FILE_ACTION_MODIFIED:
break;
case FILE_ACTION_RENAMED_OLD_NAME:
break;
case FILE_ACTION_RENAMED_NEW_NAME:
break;
}
dwOffset += pInfo->NextEntryOffset;
}
while (pInfo->NextEntryOffset != 0);
Re: Multiple Files with ReadDirectoryChangesW
Thanks for that snippet Bond. I tried your code but still no matter how many files I drop into the watched directory, I only ever get the 1st filename.
Anyone got any suggestions? Or do I have to re-structure my code to support Overlapped IO?
Thanks!