?
Hallo!
Hier und da was gelesen und bißchen Code "geklaut" half mir, mein Programm "umzukrempeln". Nun kann ich auch mit "ReadDirectoryChangesW" erstmal ein (einzelnes) Verzeichnis überwachen und die Veränderungen dort abfangen.
Für diejenigen, die sich dafür interessieren, Code folgt (vielleicht kann ihn jemand von den Profis optimieren und für die anderen, die so etwas suchen, zur Verfügung stellen)
HANDLE FDirectoryHandle;
TWatchThread *FWatchThread;
//HANDLE FCompletionPort;
DWORD FBytesWritten, FNotifyFilter;
BYTE FNotificationBuffer[4];
DWORD numBytes;
TOverlapped FOverlapped;
POverlapped FPOverlapped;
void __fastcall TForm1::FormCreate(TObject *Sender)
{
//FCompletionPort = 0;
FDirectoryHandle = 0;
FPOverlapped = &FOverlapped;
ZeroMemory(&FOverlapped, sizeof(FOverlapped));
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
btnStopClick(Sender);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::btnStopClick(TObject *Sender)
{
/*if (FCompletionPort == 0)
return;
PostQueuedCompletionStatus(FCompletionPort, 0, 0, NULL);
FWatchThread->WaitFor();
FWatchThread->Free(); */
CloseHandle(FDirectoryHandle);
FDirectoryHandle = 0;
//CloseHandle(FCompletionPort);
//FCompletionPort = 0;
edPath->Enabled = true;
btnStart->Enabled = true;
btnStop->Enabled = false;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::btnStartClick(TObject *Sender)
{
lbEvents->Clear();
FNotifyFilter = 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;
FDirectoryHandle = CreateFile(edPath->Text.c_str(),
FILE_LIST_DIRECTORY, FILE_SHARE_READ |
FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
0);
if (FDirectoryHandle == INVALID_HANDLE_VALUE)
{
Beep();
FDirectoryHandle = 0;
ShowMessage(SysErrorMessage(GetLastError()));
return;
}
//FCompletionPort = CreateIoCompletionPort(FDirectoryHandle, 0, (long int)(this), 0);
ZeroMemory(FNotificationBuffer, sizeof(FNotificationBuffer));
FBytesWritten = 0;
if (!ReadDirectoryChangesW(FDirectoryHandle, FNotificationBuffer,
sizeof(FNotificationBuffer), true, FNotifyFilter,
&FBytesWritten, &FOverlapped, NULL))
{
CloseHandle(FDirectoryHandle);
FDirectoryHandle = 0;
//CloseHandle(FCompletionPort);
//FCompletionPort = 0;
ShowMessage(SysErrorMessage(GetLastError()));
return;
}
edPath->Enabled = false;
btnStart->Enabled = false;
btnStop->Enabled = true;
FWatchThread = new TWatchThread(this);
TWatchThread(FWatchThread).Resume();
}
//---------------------------------------------------------------------------
__fastcall TWatchThread::TWatchThread(bool CreateSuspended) : TThread(CreateSuspended)
{
FreeOnTerminate = true; //Aufruf von TThread::Terminate() gibt Thread frei.
}
//---------------------------------------------------------------------------
_fastcall TWatchThread::~TWatchThread()
{
TThread::inherited(); //Standarddestruktor.
}
//---------------------------------------------------------------------------
void __fastcall TWatchThread::Execute()
{
while (!Terminated)
{
/*GetQueuedCompletionStatus(FCompletionPort, &numBytes, &CompletionKey, &FPOverlapped, INFINITE);
if (CompletionKey != 0 )*/
if(WaitForSingleObject(FDirectoryHandle, INFINITE) == WAIT_OBJECT_0)
//if(WaitForMultipleObjects(iAnzahl, FDirectoryHandle, true, INFINITE) == WAIT_OBJECT_0)
{
Synchronize(Events);
FBytesWritten = 0;
ZeroMemory(FNotificationBuffer, sizeof(FNotificationBuffer));
ReadDirectoryChangesW(FDirectoryHandle, FNotificationBuffer, sizeof(FNotificationBuffer),
true, FNotifyFilter, &FBytesWritten, &FOverlapped, NULL);
}
else
Terminate();
}
}
//---------------------------------------------------------------------------
void __fastcall TWatchThread::Events()
{
Form1->lbEvents->Items->Add(Now());
}
//---------------------------------------------------------------------------
Mein Problem besteht aber dennoch darin, mehrere Verzeichnisse gleichzeitig und permanent zu überwachen. Mit "WaitForMultipleObjects" sollte das eigentlich gehen, aber ich habe es bis jetzt ehrlich gesagt nicht geschafft.
Wie soll ich da vorgehen?
Kann mir da vielleicht jemand helfen?
Danke!