You have to write some monitoring code. This was a big project for me about 6 months ago, I found that the best way to do it is with the ReadDirectoryChangesW() API. The problem I had was all of the articles/examples I found were either bloated and sloppy or not usable. My next article will be to publish my monitor code but if you need quick results start there (ReadDirectoryChangesW).
heres some example code, I tried to clean it up some for you, its purpose was to monitor xml files in a directory for changes, when a file was edited it would compare the files and report the differences. This example is only monitoring one directory now but I know its possible to monitor many:
DWORD WatchThread(CDataMonitor* pThis)
{
ASSERT(pThis);
....
pThis->m_olWatch.hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
HANDLE hEvents[2];
hEvents[0] = pThis->m_hStopEvents[1];
hEvents[1] = pThis->m_olWatch.hEvent;
DWORD dwBytesReturned = 0;
FILE_NOTIFY_INFORMATION buffer[1024] = {0};
CString strRenameFileOld = _T("");
while(TRUE)
{
if(!::ReadDirectoryChangesW(pThis->m_hWatchDirectory, &buffer, sizeof(buffer), FALSE,
FILE_NOTIFY_CHANGE_CREATION|FILE_NOTIFY_CHANGE_ATTRIBUTES|FILE_NOTIFY_CHANGE_LAST_WRITE|
FILE_NOTIFY_CHANGE_FILE_NAME, &dwBytesReturned, &pThis->m_olXMLWatch, NULL))
{
pThis->OnWindowsError(_T("WatchThread"), _T("ReadDirectoryChangesW"),
_T("Starting XML directory monitor"));
pThis->m_pMonitorThread = NULL;
AfxEndThread(0, TRUE);
ASSERT(0);
return 0;
}
DWORD dwWait = ::WaitForMultipleObjects(2, hEvents, FALSE, INFINITE);
if(dwWait ==WAIT_OBJECT_0)
{
AfxEndThread(1, FALSE);
return 1;
}
::ResetEvent(hEvents[1]);
int i = 0;
do
{
CString strFileName = CString(buffer[i].FileName).Left(buffer[i].FileNameLength / 2);
.......
TCHAR szCompareFile[MAX_PATH] = {NULL};
_tcscpy(szCompareFile, szDir);
_tcscpy(szCompareFile + _tcslen(szCompareFile), FileName);
TCHAR szBackupFile[MAX_PATH] = {NULL};
_tcscpy(szBackupFile, szBackupPath);
_tcscpy(szBackupFile + _tcslen(szBackupFile), FileName);
#ifdef _DEBUG
CString strStatusText = _T("");
CTime tm = CTime::GetCurrentTime();
strStatusText = tm.Format("%H:%M:%S - ");
#endif
CString strStatusDesc = _T("");
switch(buffer[i].Action)
{
case FILE_ACTION_ADDED:
{
strStatusDesc = _T("File added to directory");
if(!::CopyFile(szCompareFile, szBackupFile, FALSE))
{
if(::GetLastError() == ERROR_SHARING_VIOLATION)
{
Sleep(100);
if(!::CopyFile(szCompareFile, szBackupFile, FALSE))
{
pThis->OnWindowsError(_T("XMLWatchThread"), _T("CopyFile"),
_T("Monitoring - Event: FILE_ACTION_ADDED"));
ASSERT(0);
}
}
}
pThis->m_csNotify.Lock();
pThis->OnFileAdded(strFileName);
pThis->m_csNotify.Unlock();
break;
}
case FILE_ACTION_REMOVED:
{
strStatusDesc = _T("File removed from directory");
if(!::DeleteFile(szBackupFile))
{
pThis->OnWindowsError(_T("WatchThread"), _T("DeleteFile"),
_T("Monitoring - Event: FILE_ACTION_REMOVED"));
}
pThis->m_csNotify.Lock();
pThis->OnFileDeleted(FileName);
pThis->m_csNotify.Unlock();
break;
}
case FILE_ACTION_MODIFIED:
{
if(!pThis->FileExists(szBackupFile))
{
strStatusDesc = _T("File renamed - this is the new name");
CString strRenameFile = pThis->m_BackupPath;
if(strRenameFile.Right(1) != _T("\\"))
strRenameFile += _T("\\");
strRenameFile += strRenameFileOld;
int iResult = _trename(strRenameFile, szBackupFile);
if(iResult != 0)
{
CString strErr = _T("");
switch(iResult) {
case 13: Err = _T("Access error, newname already exists or could not be created"); break;
case 2 : Err = _T("File or path specified by oldname not found"); break;
case 22: Err = _T("Name contains invalid TCHARacters"); break;
}
pThis->m_csNotify.Lock();
pThis->m_strLastError.Format(
_T("Function: WatchThread - _trename Failed - Error %d: %s"), iResult, Err);
pThis->OnError(pThis->m_LastError);
pThis->m_csNotify.Unlock();
}
pThis->m_csNotify.Lock();
pThis->OnFileRenamed(strRenameFileOld, strFileName);
pThis->m_csNotify.Unlock();
break;
}
strStatusDesc = _T("File modified - time stamp or attributes");
if(pThis->CompareFileProperties(szCompareFile, szBackupFile) > 0)
{
pThis->m_csWorkList.Lock();
POSITION pos = pThis->m_cslWorkList.Find(FileName);
if(pos == NULL)
pThis->m_cslWorkList.AddTail(FileName);
pThis->m_csWorkList.Unlock();
}
break;
}
case FILE_ACTION_RENAMED_OLD_NAME:
{
strStatusDesc = _T("File renamed - this is the old name");
strRenameFileOld = strFileName;
break;
}
case FILE_ACTION_RENAMED_NEW_NAME:
{
strStatusDesc = _T("File renamed - this is the new name");
ASSERT(0);
break;
}
}
#ifdef _DEBUG
strStatusText += strFileName;
strStatusText += _T(" - ");
strStatusText += strStatusDesc;
pThis->m_csNotify.Lock();
pThis->OnStatusUpdate(strStatusText);
pThis->m_csNotify.Unlock();
#endif
}
}
while(!buffer[++i].NextEntryOffset);
}
return 1;
}
I hope this helps, good luck