wieder mal ein Problem, diesesmal geht es um ReadDirectoryChangesW() und dem WaitForMultipleObjects()
habe nach allen möglichen gesucht bin auch zum Teil fündig geworden, nur leider scheitere ich am Abbruch der Überwachung für ein Verzeichnis,
da ja ReadDirectoryChangesW() weiterhin auf ein Event wartet.
Ich habe dann etwas unter Delphi gefunden, wo eben mittels WaitForMultipleObjects() ein Abbruch erzeugt werden kann, leider
bekomme ich das nicht in Purebasic übersetzt , hoffe das ihr mir mal wieder da weiter helfen könnt
Her der Delphi Code
und Hier eine Purebasic Variante aber eben ohne Abbruchpublic:
/**
* Thread procedure
*/
void run()
{
looping = true;
const TCHAR* dir = (const TCHAR*)directory;
if (GetFileAttributes(dir) == 0xffffffff) {
//2008/09/24 Should be changed to be able to make multiple subdirectories
if (CreateDirectory(dir, NULL)) {
_tprintf(_T("Create a new directory %s\n"), dir); //2012/06/22
}
}
this->hFolder = CreateFile(dir,
FILE_LIST_DIRECTORY,
FILE_SHARE_READ|FILE_SHARE_DELETE,
NULL,
OPEN_EXISTING,
// Specify FILE_FLAG_OVERLAPPED flags
FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OVERLAPPED,
NULL);
if(this->hFolder == INVALID_HANDLE_VALUE){
_tprintf(_T("Failed to open dir %s\n"), dir); //2012/06/22
return;
}
OVERLAPPED ol;
ol.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
HANDLE waitEvents[2];
waitEvents[0] = terminateEvent;
waitEvents[1] = ol.hEvent;
//Start a loop of call ReadDirectoryChangesW().
while(looping) {
DWORD dwBytes = 0;
TCHAR buf[1024];
BOOL rc = ReadDirectoryChangesW(hFolder, buf, 1022,1,
this->filters,
/*
//2008/12/10
FILE_NOTIFY_CHANGE_DIR_NAME |
FILE_NOTIFY_CHANGE_FILE_NAME |
FILE_NOTIFY_CHANGE_LAST_ACCESS |
FILE_NOTIFY_CHANGE_ATTRIBUTES |
FILE_NOTIFY_CHANGE_SIZE |
FILE_NOTIFY_CHANGE_LAST_WRITE|
FILE_NOTIFY_CHANGE_CREATION |
FILE_NOTIFY_CHANGE_SECURITY,
*/
&dwBytes, &ol, NULL);
if (rc == FALSE) {
printf("Failed:ReadDirectoryChanges()\n");
break;
}
if (looping == false) {
printf("looping ends\n");
break;
}
int r = WaitForMultipleObjects(2, waitEvents, FALSE, INFINITE );
if (r == WAIT_OBJECT_0 ) {
//printf("Stopped 0\n");
printf("\nTerminateEvent has been set, so break this thread loop\n");
break;
}
BOOL b = GetOverlappedResult(hFolder, &ol, &dwBytes, TRUE );
if (b == FALSE) {
continue;
}
//printf("buf ReadSize=%d\n",dwBytes);
FILE_NOTIFY_INFORMATION *fn = (FILE_NOTIFY_INFORMATION *)buf;
while (fn) {
//FileName will be "NULL" terminated
fn->FileName[fn->FileNameLength/2] = 0;
wchar_t * action = L"";
switch(fn->Action){
case FILE_ACTION_ADDED:
action = L"Added";
break;
case FILE_ACTION_REMOVED:
action = L"Removed";
break;
case FILE_ACTION_MODIFIED:
action = L"Accessed/Modified";
break;
case FILE_ACTION_RENAMED_OLD_NAME:
action = L"Renamed(Old name)";
break;
case FILE_ACTION_RENAMED_NEW_NAME:
action = L"Renamed(New name)";
break;
default:
action = L"(Unknown)";
}
changedFileName(action, fn->FileName);
if (fn->NextEntryOffset == NULL) {
break;
} else {
fn = (FILE_NOTIFY_INFORMATION *)(((char *)fn) + fn->NextEntryOffset);
}
} //while
}
CloseHandle(ol.hEvent);
close();
}
};
}
Code: Alles auswählen
EnableExplicit
; überwachung Constanten
#FILE_NOTIFY_CHANGE_FILE_NAME = 1
#FILE_NOTIFY_CHANGE_DIR_NAME = 2
#FILE_NOTIFY_CHANGE_ATTRIBUTES = 4
#FILE_NOTIFY_CHANGE_SIZE = 8
#FILE_NOTIFY_CHANGE_LAST_WRITE = $10
#FILE_NOTIFY_CHANGE_LAST_ACCESS = $20
#FILE_NOTIFY_CHANGE_CREATION = $40
#FILE_NOTIFY_CHANGE_SECURITY = $100
#FILE_NOTIFY_CHANGE_ALL = $17F
#FILE_SHARE_DELETE = 4
#FILE_ACTION_ADDED = 1
#FILE_ACTION_REMOVED = 2
#FILE_ACTION_MODIFIED = 3
#FILE_ACTION_RENAMED_OLD_NAME = 4
#FILE_ACTION_RENAMED_NEW_NAME = 5
Import "kernel32.lib"
ReadDirectoryChangesW(a, b, c, d, e, f, g, h)
EndImport
Structure FILE_NOTIFY_INFORMATION ;für ReadDirectoryChangesW
NextEntryOffset.l
Action.l : stop.i
FileNameLength.l
Filename.s{255}
EndStructure
Structure Thread ; ThreadStruktur
Thread.i
Stop.i
Mutex.i
Pfad.s
EndStructure
Global.Thread Watch
Procedure WatchFiles(f) ;Thread von ReadDirectoryChangesW
Protected DirectoryName.s=Watch\Pfad
Protected NotifyFilter.l = #FILE_NOTIFY_CHANGE_ALL
Protected buffer.FILE_NOTIFY_INFORMATION, ovlp.OVERLAPPED
Protected Filename.s
Protected hDir,a
Protected bytesRead
Protected path$,item.i
hDir = CreateFile_(DirectoryName, #FILE_LIST_DIRECTORY, #FILE_SHARE_READ | #FILE_SHARE_WRITE | #FILE_SHARE_DELETE, #Null, #OPEN_EXISTING, #FILE_FLAG_BACKUP_SEMANTICS, #Null)
Debug "Überwachung von "+DirectoryName+" gestartet !"
Repeat
If Watch\Stop : Break : EndIf ; wird erst augeführt sobald ReadDirectoryChangesW etwas regestiert (Problem !!!!)
ReadDirectoryChangesW(hDir, @buffer, SizeOf(FILE_NOTIFY_INFORMATION), #True, NotifyFilter, bytesRead, ovlp, 0)
Filename = PeekS(@buffer\Filename, -1, #PB_Unicode)
Debug "Überwachung läuft !"
path$=GetPathPart(DirectoryName+Filename)
If FindString(path$,Watch\Pfad)
Select buffer\Action
Case #FILE_ACTION_ADDED
Debug "Added File: "+Filename
Case #FILE_ACTION_REMOVED
Debug "Remove File: "+Filename
Case #FILE_ACTION_MODIFIED
Debug "Modifed File: "+Filename
Case #FILE_ACTION_RENAMED_OLD_NAME
;Dateiumbenennung: Alter Dateiname
Case #FILE_ACTION_RENAMED_NEW_NAME
;Dateiumbenennung: Neuer Dateiname
EndSelect
EndIf
buffer\Filename = ""
ForEver
Debug "Überwachung von "+DirectoryName+" des Listfenster00 abgebrochen !"
EndProcedure
Procedure StartWatchVerzeichnis(Pfad.s) ;Threadaufruf für ReadDirectoryChangesW
If IsThread(Watch\Thread)
Debug "Überwachung von "+Watch\Pfad+" abgebrochen !"
Watch\stop= #True
EndIf
Watch\Pfad=Pfad
Watch\stop=0
Watch\Thread=CreateThread(@WatchFiles(),@Watch)
EndProcedure
If OpenWindow(0,0,0,500,400,"Warte auf Debug",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
StartWatchVerzeichnis("c:\")
EndIf
Repeat
Define event = WaitWindowEvent()
Until event=#PB_Event_CloseWindow