Je suis en train de coder un dossier de programmation à regarder. J'utilise la bibliothèque FileWatch.h
. Ceci est mon FileWatch.h
Accédez à l'emplacement de lecture de violation 0xba2f1498
#ifndef FILEWATCH_H
#define FILEWATCH_H
class FileChangeObserver
{
public:
virtual ~FileChangeObserver()
{
}
virtual void OnFileChanged() = 0;
};
// information concerning a directory being watched
class FileWatcher
{
public:
// Watching file modifications using a loop
void Init(LPCTSTR filefullpath);
bool CheckForChanges(DWORD waittime=0);
// Watching file modification via a thread
void StartWatchThread();
bool IsThreadRunning();
void SynchronousAbort();
FileWatcher(FileChangeObserver *observer) : hDir(NULL), curBuffer(0),
filePath(NULL), hWatchingThread(NULL), observer(observer)
{
ZeroMemory(&this->overl, sizeof(this->overl));
// create the event used to abort the "watching" thread
hEvtStopWatching = CreateEvent(NULL, TRUE, FALSE, NULL);
}
FileWatcher()
{
}
~FileWatcher()
{
SynchronousAbort();
delete observer;
free(filePath);
CloseHandle(hEvtStopWatching);
}
public:
HANDLE hDir; // handle of the directory to watch
FileChangeObserver *observer; // function called when a file change is detected
TCHAR * filePath; // path to the file watched
FILE_NOTIFY_INFORMATION buffer[2][512];
// a double buffer where the Windows API ReadDirectory will store the list
// of files that have been modified.
int curBuffer; // current buffer used (alternate between 0 and 1)
bool NotifyChange();
public:
// fields for use by the WathingThread
OVERLAPPED overl; // object used for asynchronous API calls
HANDLE hWatchingThread; // handle of the watching thread
HANDLE hEvtStopWatching; // this event is fired when the watching thread needs to be aborted
};
static DWORD WINAPI WatchingThread(void *param);
#endif
Ceci est mon FileWatch.cpp
#include "stdafx.h"
#include "FileWatch.h"
#include "assert.h"
#if _MSC_VER > 1600
extern "C" {
WINBASEAPI BOOL WINAPI
GetOverlappedResult(_In_ HANDLE hFile, _In_ LPOVERLAPPED lpOverlapped, _Out_ LPDWORD lpNumberOfBytesTransferred, _In_ BOOL bWait);
}
#endif
bool FileWatcher::IsThreadRunning()
{
return hWatchingThread && (WaitForSingleObject(hWatchingThread, 0) == WAIT_TIMEOUT);
}
// Ask for the thread to stop and waith until it ends
void FileWatcher::SynchronousAbort()
{
SetEvent(hEvtStopWatching);
if (hWatchingThread)
{
WaitForSingleObject(hWatchingThread, INFINITE);
CloseHandle(hWatchingThread);
Sleep(500);
hWatchingThread = NULL;
}
CloseHandle(overl.hEvent);
overl.hEvent = NULL;
CloseHandle(hDir);
hDir = NULL;
}
// Start watching a file for changes
void FileWatcher::StartWatchThread()
{
// if the thread already exists then stop it
if (IsThreadRunning())
SynchronousAbort();
assert(hDir);
if (!hDir)
{
return;
}
// reset the hEvtStopWatching event so that it can be set if
// some thread requires the watching thread to stop
ResetEvent(hEvtStopWatching);
DWORD watchingthreadID;
hWatchingThread = CreateThread(NULL, 0, WatchingThread, this, 0, &watchingthreadID);
}
void FileWatcher::Init(const TCHAR* fileFullPath)
{
// if the thread already exists then stop it
if (IsThreadRunning())
SynchronousAbort();
// str::ReplacePtr(&filePath, fileFullPath);
//TCHAR *dirPath = path::GetDir(filePath);
hDir = CreateFile(
L"C:\\", // pointer to the directory containing the tex files
FILE_LIST_DIRECTORY, // access (read-write) mode
FILE_SHARE_READ|FILE_SHARE_DELETE|FILE_SHARE_WRITE, // share mode
NULL, // security descriptor
OPEN_EXISTING, // how to create
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED , // file attributes
NULL); // file with attributes to copy
// free(dirPath);
ZeroMemory(&overl, sizeof(overl));
ZeroMemory(buffer, sizeof(buffer));
overl.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
// watch the directory
ReadDirectoryChangesW(
hDir, /* handle to directory */
&buffer[curBuffer], /* read results buffer */
sizeof(buffer[curBuffer]), /* length of buffer */
FALSE, /* monitoring option */
//FILE_NOTIFY_CHANGE_CREATION|
FILE_NOTIFY_CHANGE_LAST_WRITE, /* filter conditions */
NULL, /* bytes returned */
&overl, /* overlapped buffer */
NULL); /* completion routine */
}
// Thread responsible of watching the directory containg the file to be watched for modifications
DWORD WINAPI WatchingThread(void *param)
{
//qDebug()<<"in WatchingThread";
FileWatcher *fw = (FileWatcher *)param;
HANDLE hp[2] = { fw->hEvtStopWatching, fw->overl.hEvent };
for (;;)
{
DWORD dwObj = WaitForMultipleObjects((sizeof(hp)/(sizeof(hp[0])))
, hp, FALSE, INFINITE);
if (dwObj == WAIT_OBJECT_0) // the user asked to quit the program
{
//qDebug()<<"in WatchingThread the user asked to quit the program";
//exit(-1);
break;
}
if (dwObj != WAIT_OBJECT_0 + 1)
{
// BUG!
//assert(0);
// qDebug()<<"dwObj "<<dwObj<<" last error "<<GetLastError();
break;
}
//qDebug()<<"WatchingThread fw->NotifyChange() ";
//if (fw->wakeup)
fw->NotifyChange();
}
return 0;
}
// Call ReadDirectoryChangesW to check if the file has changed since the last call.
bool FileWatcher::CheckForChanges(DWORD waittime)
{
if (!overl.hEvent)
{
return false;
}
DWORD dwObj = WaitForSingleObject(overl.hEvent, waittime);
if (dwObj != WAIT_OBJECT_0)
{
return false;
}
return NotifyChange();
}
// Call the ReadDirectory API and determine if the file being watched has been modified since the last call.
// Returns true if it is the case.
bool FileWatcher::NotifyChange()
{
//qDebug()<<"in NotifyChange";
DWORD dwNumberbytes;
GetOverlappedResult(hDir, &overl, &dwNumberbytes, FALSE);
FILE_NOTIFY_INFORMATION *pFileNotify = (FILE_NOTIFY_INFORMATION *)buffer[curBuffer];
// Switch the 2 buffers
curBuffer = (curBuffer + 1) % (sizeof(buffer)/(sizeof(buffer[0])));
SecureZeroMemory(buffer[curBuffer], sizeof(buffer[curBuffer]));
// start a new asynchronous call to ReadDirectory in the alternate buffer
ReadDirectoryChangesW(
hDir, /* handle to directory */
&buffer[curBuffer], /* read results buffer */
sizeof(buffer[curBuffer]), /* length of buffer */
TRUE, /* monitoring option */
FILE_NOTIFY_CHANGE_FILE_NAME |
FILE_NOTIFY_CHANGE_DIR_NAME |
FILE_NOTIFY_CHANGE_ATTRIBUTES |
FILE_NOTIFY_CHANGE_SIZE |
FILE_NOTIFY_CHANGE_LAST_WRITE |
FILE_NOTIFY_CHANGE_LAST_ACCESS |
FILE_NOTIFY_CHANGE_CREATION |
FILE_NOTIFY_CHANGE_SECURITY,
//FILE_NOTIFY_CHANGE_LAST_WRITE, /* filter conditions */
NULL, /* bytes returned */
&overl, /* overlapped buffer */
NULL); /* completion routine */
// Note: the ReadDirectoryChangesW API fills the buffer with WCHAR strings.
for (;;)
{
if (pFileNotify->Action == FILE_ACTION_ADDED)
{
//qDebug()<<"in NotifyChange if ";
char szAction[42];
char szFilename[MAX_PATH] ;
memset(szFilename,'\0',sizeof(szFilename));
strcpy(szAction,"added");
wcstombs(szFilename, pFileNotify->FileName, MAX_PATH);
if(observer)
observer->OnFileChanged();
return true;
//OnFileChanged(szFilename,szAction);
// qDebug()<<"in NotifyChange after OnFileChanged ";
}
// step to the next entry if there is one
if (!pFileNotify->NextEntryOffset)
{
return false;
}
pFileNotify = (FILE_NOTIFY_INFORMATION *)((PBYTE)pFileNotify + pFileNotify->NextEntryOffset);
}
pFileNotify=NULL;
return true;
}
Dans le programme principal, je:
case IDM_ABOUT:
//DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
{
FileWatcher *cWatcher = new FileWatcher();
cWatcher->Init(L"AB");
cWatcher->NotifyChange();
break;
}
J'ai une erreur messeage que: violation d'accès lecture emplacement 0xba2f1498. Quelle est la solution?
Personne ne va démêler ce gâchis. Vous devez fournir la trace du débogueur. Le problème se résume à accéder à la mémoire que vous n'êtes pas censé accéder, mais il est difficile de dire où exactement, sauf si vous postez la trace du débogueur. Alors développez votre question pour obtenir de l'aide. –
Je vois un 'delete observer' et' free (filePath) 'mais pas de code qui alloue de la mémoire pour l'un ou l'autre, outre le fait que vous mélangez l'allocation de style c et l'allocation de style C++ ensemble. –
@Haroogan Je veux changer de répertoire, puis-je utiliser ce code? tout changement dans le dossier: supprimer le dossier, nouveau dossier, renommer ... Je ne sais pas comment les attraper. – user2284783