-
October 18th, 2007, 07:22 AM
#1
How to monitor a folder?
Q: How can I monitor a given folder to see, for example, when a file was added, deleted, or modified?
A: An easy way is to use FindFirstChangeNotification, FindNextChangeNotification and one of the wait functions in a worker thread. As for example:
Code:
DWORD WINAPI FolderFilesWatchDogThread(LPVOID lpParam) // thread procedure
{
HANDLE hFileChange =
::FindFirstChangeNotification((LPCTSTR)lpParam, // folder path
FALSE, // don't look in subfolders
FILE_NOTIFY_CHANGE_FILE_NAME);
// watch for
// renaming, creating,
// or deleting a file
if(INVALID_HANDLE_VALUE == hFileChange)
{
DWORD dwError = ::GetLastError();
// handle error (see this FAQ)
return dwError;
}
while(TRUE)
{
::WaitForSingleObject(hFileChange, INFINITE);
// Bark, bark!!! A file was renamed, created or deleted.
::FindNextChangeNotification(hFileChange);
}
return 0;
}
// somewhere in the space...
::CreateThread(NULL, 0, FolderFilesWatchDogThread, _T("c:\\temp"), 0, NULL);
A little bit more sophisticated but offering more info (like the name of the file) is to use ReadDirectoryChangesW.
Also, here is a simplified example:
Code:
DWORD WINAPI FolderWatchThread(LPVOID lpParam) // thread procedure
{
HANDLE hDirectory =
::CreateFile((LPCTSTR)lpParam, // folder path
FILE_LIST_DIRECTORY,
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
if(INVALID_HANDLE_VALUE == hDirectory)
{
DWORD dwError = ::GetLastError();
// handle error (see this FAQ)
return dwError;
}
DWORD dwBytesReturned = 0;
const DWORD dwBuffLength = 4096;
BYTE buffer[dwBuffLength];
WCHAR wchFileName[_MAX_PATH + 1];
while(::ReadDirectoryChangesW(hDirectory, buffer, dwBuffLength, FALSE,
FILE_NOTIFY_CHANGE_FILE_NAME, &dwBytesReturned,
NULL, NULL))
{
DWORD dwNextEntryOffset = 0;
PFILE_NOTIFY_INFORMATION pfni = NULL;
do
{
pfni = (PFILE_NOTIFY_INFORMATION)(buffer + dwNextEntryOffset);
switch(pfni->Action)
{
case FILE_ACTION_ADDED:
// The file was added to the directory.
break;
case FILE_ACTION_REMOVED:
// The file was removed from the directory.
break;
case FILE_ACTION_RENAMED_OLD_NAME:
// The file was renamed and this is the old name.
break;
case FILE_ACTION_RENAMED_NEW_NAME:
// The file was renamed and this is the new name.
break;
// ...
}
memcpy(wchFileName, pfni->FileName, pfni->FileNameLength);
wchFileName[pfni->FileNameLength / sizeof(WCHAR)] = L'\0';
// Enjoy of added, removed, or modified file name...
dwNextEntryOffset += pfni->NextEntryOffset; // next please!
}while(pfni->NextEntryOffset != 0);
}
::CloseHandle(hDirectory);
return 0;
}
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|