ReadDirectoryChangesW
-
hallo
ich habe einen windowsdienst geschrieben (begonnen zu schreiben...) welcher ein bestimmtes
verzeichnis und dessen unterverzeichnis auf erstellen von dateien überwachen soll um dann aktionen mit diesen auszuführen(kopieren).der dienst ist allerdings noch nicht fertig; im moment gibt er nur eine meldung
in der ereignisanzeige aus, ob eine datei erstellt worden ist. das funktioniert
soweit auch gut, nur, dass sobald ich die routine ReadDirectoryChangesW(...) aufrufe,
der dienst beim stop über die dienstkonsole die meldung "...konnte nicht beendet werden ...." + "... der dienst hat keinen fehler zurrückgegeben..." erscheint. wenn ich die routine ReadDirectoryChangesW(...) auskommentiere, dann funktioniert es wieder wunderbar.hier der qtext;
methode einer eigenen klasse, welche mir - wenn sie fertig ist - den pfad\dateinamen der neu erstellten datei zurrückgeben soll:AnsiString __fastcall TFunct::watchDir() { AnsiString *trFile; trFile = new AnsiString; FILE_NOTIFY_INFORMATION *inf; inf = new FILE_NOTIFY_INFORMATION; DWORD bufLen = pow(2,16); void *pBuf = AllocMem(bufLen); unsigned long *dwRead; char *c; c = new char[(*INPATH).Length() + 1]; strcpy(c, (*INPATH).c_str()); HANDLE hNotify = FindFirstChangeNotification(c, true, FILE_NOTIFY_CHANGE_FILE_NAME); if (hNotify == INVALID_HANDLE_VALUE) { *trFile = "noHandle"; } else { if((ReadDirectoryChangesW(hNotify, pBuf, bufLen, true, FILE_NOTIFY_CHANGE_FILE_NAME, dwRead, NULL, NULL)) != 0) { //inf = ((FILE_NOTIFY_INFORMATION*) (*inf).FileName); *trFile = "OP"; } else { *trFile = GetLastError(); } } CloseHandle(hNotify); return *trFile; }und der aufruf via ServiceExecute:
void __fastcall TEFofmngr::ServiceExecute(TService *Sender) { if ((!DirectoryExists(PATH2CFG)) || (!FileExists(CFG))) { LogMessage("cfg not found!(checkPath and cfg)", EVENTLOG_ERROR_TYPE, 999, 4); } else { (*f1).pathConfig("C:\\Program Files\\Filemgr\\manCfg.cfg"); //check if sPath and dPath is available if (DirectoryExists((*f1).getInPath()) && DirectoryExists((*f1).getOutPath())) { (*f1).setGo(true); LogMessage("inPath: "+(*f1).getInPath()+"\\\~", EVENTLOG_SUCCESS, 999, 1); LogMessage("outPath: "+(*f1).getOutPath()+"\\\~", EVENTLOG_SUCCESS, 999, 1); } else { (*f1).setGo(false); LogMessage((*f1).getInPath()+" or "+ (*f1).getOutPath()+" not found!", EVENTLOG_ERROR_TYPE, 999, 4); } //---- if ((*f1).getGo()) { //------------------------------------- while ((*f1).getGo()) { LogMessage((*f1).watchDir(), EVENTLOG_SUCCESS, 999, 1); (*ServiceThread).ProcessRequests(false); } //------------------------------------ } else { bool b = (*f1).getGo(); ServiceStop(Sender, b); } } }in der service stop routine steht:
void __fastcall TEFofmngr::ServiceStop(TService *Sender, bool &Stopped) { LogMessage("FileManager Stopped", EVENTLOG_INFORMATION_TYPE, 999, 2); (*f1).setGo(false); ErrCode = 0; Win32ErrCode = 0; Stopped = true; (*f1).~TFunct(); }die meldung "FileManager Stopped" wird allerdings nie ausgegeben, sobald ich ReadDirectoryChangesW einbinde!
mein system ist vista 64, codegear c++ 2009 als ide.
nach ner menge googlerei, welche mir noch nicht die lösung "brachte"
meine frage nun an euch: kann mir jemand sagen, was ich falsch mache?danke für jede hilfe
peter
-
Du solltest dir nochmal die Doku anschauen.
ReadDirectoryChangesWblockiert, die Funktion kehrt also erst zurück, wenn eine Änderung gemeldet wird.Abgesehen davon stimmt das sowieso alles nicht so ganz. Ich kenne es so, dass man entweder
FindFirst/NextChangeNotificationnutzt oder aber ReadDirectoryChangesW, aber nicht beides vermischt.Mit
FindFirst/NextChangeNotificationbekommst du afair nur mit, dass etwas geändert wurde, aber nicht den entsprechenden Pfad. Dafür kannst du bequem mit mit denWaitFor..-Funktionen darauf warten bzw den Status checken. Das Handle vonFindFirstChangeNotificationschließt man übrigens mitFindCloseChangeNotification.
Wenn duReadDirectoryChangesnutzt, solltest du sie asynchron einsetzen, da du ja regelmäßig deineProcessRequests-Funktion aufrufen willst.Zusätzlich zu Doku und Beispielen in der MSDN gibt's sicherlich auch bei CodeProject ein oder zwei Beispielprogramme.
-
hallo
ertmal danke für die antwort;
das "der wurm" drinnen ist hab ich mir schon gedacht, ist das erste mal, dass
ich mich mit winapi beschäftige.frage:
wie soll ich sonst zum handle auf die (in diesem fall) neu erstellte datei
kommen, wenn nicht überFindFirstChangeNotification?
wie muss ich dieWaitFor..-Funktionen einsetzen?
(ich vermute, es handelt sich dabei umwaitforsingleobject)
kann ich die anstattReadDirectoryChangesWverwenden?kannst du mir ein konkretes beispiel nennen?
sorry für meine <unwissenheit>, aber ich such enur (noch) den faden für den richtigen
anfang.peter
-
Hast Du mal in der MSDN die Doku gelesen zu FindFirstChangeNotification?
http://msdn.microsoft.com/en-us/library/aa364417(VS.85).aspxDort findest Du unten einen Verweis auf ein Sample:
http://msdn.microsoft.com/en-us/library/aa365261(VS.85).aspxDort werden Deine Fragen beantwortet, oder?
-
oh klar - vor allem der 2. link
thanx!!!
peter