Hot Hot Hotfolder?

  • Moinsen,

    einen Ordner "rund um de Uhr" zu überwachen um festzustellen ob Files "auftauchen" und dann dem Script bestimmte Aktionen ausführen zu lassen ist ja perse erst mal kein Hexenwerk. Mit ... if FileExists und einer Schleife ist das vordergründig erledigt. Damit dieser "Überwacher keine sinnlose Prozessor/Resourcen Last erzeugt, hätte ich die Schleife mit einem Sleep immer für ein oder zwei oder auch 5 Minuten "schlafen" gelegt - je nachdem wie schnell die Überwachung gefragt ist. Gibt es dagegen etwas einzuwenden? Gibt es ein "besseres", profesionelleres Vorgehen?

    Danke für Euren Rat.

    Peter

    Hinweise auf Suchmaschinen finde ich überflüssig - wer fragt hat es nicht gefunden oder nicht verstanden. Die Antwort gibt sich oftmals schneller als der Hinweis auf Dr. Goggle & Co.

    Ab 19-10-22 ergänzt um:

    Die Welt wird nicht bedroht von den Menschen, die böse sind, sondern von denen, die das Böse zulassen. (Albert Einstein)

  • Eventbasiert wäre das ganze viel besser, da kann dein Script so lange schlafen bis es von Windows aufgeweckt wird.

    Was du suchst ist ein FileSystemWatcher. Für C# gibts das bereits in der msdn: https://msdn.microsoft.com/en-us/library/…(v=vs.110).aspx

    Auf die schnelle habe ich nur das hier gefunden: https://www.autoitscript.com/forum/topic/53…watchermonitor/

    Das hier schaut auch sehr vielversprechend aus: class FileSystemWatcher -> SHChangeNotifyRegister

    Mit dem SHChangeNotifyRegister habe ich eine Datei aus dem Verzeichnis löschen können und es wurde mir direkt in der Konsole geloggt.

  • Ja - anstatt selbst dauernd zu prüfen Windows sagen es soll deinem Skript Bescheid geben wenn sich in dem Verzeichnis was getan hat.

    Hier mal ein grober Aufbau den man noch auf die benötigten Events ausdünnen kann:

    • Offizieller Beitrag

    Mist, da schreibe ich gerade noch an einem kleinen Beispiel und ihr kloppt hier alles voll mit Lösungen. :)

    Na egal, dann gibt es halt eine Lösung mehr:

  • So da haben wir es mal wieder. Ich bin platt.

    Habe aber trotzdem eine ketzerische Betrachtung.

    Wenn große Verzeichnisstrukturen zu überwachen sind, ist mir, ohne dass ich Eure Ansätze ganz durchschaue, klar, das ist der einfachere Weg. Wenn sich unter 500 Dateien etwas ändert - soll wWindows das melden.

    Gibt es aber tatsächlich einen Resourcenunterschied wenn in dem zu überwachenden Verzeichnis:

    1tes keine Uterverzeichnisse vorhanden sind

    2tens keine Dateien vorhanden sind, da diese nur dort abgestellt werden, verarbeitet werden, gelöscht werden?

    Ich prüfe also ein per se ein leeres Verzeichnis. Sofern Inhalt genügt eine Datei um in die Verarbeitungsschleife einzutreten?

    Ja, ich gebs zu! Eure Lösungen muß ich erst verstehen lernen, Zeit ist knapp, und was ich nicht verstehe benutze ich es ungern. Anders ausgedrückt - ich hatte eine Frage gestellt und bin mit der Antwort unzufrieden (obwohl diese ja eigentlich eingefordert habe).

    Unter meinem nachgereichten Szenario macht es praktisch relevanten Unterschied?


    Danke

    Peter

    Hinweise auf Suchmaschinen finde ich überflüssig - wer fragt hat es nicht gefunden oder nicht verstanden. Die Antwort gibt sich oftmals schneller als der Hinweis auf Dr. Goggle & Co.

    Ab 19-10-22 ergänzt um:

    Die Welt wird nicht bedroht von den Menschen, die böse sind, sondern von denen, die das Böse zulassen. (Albert Einstein)

  • Bei deiner Lösung wird periodisch Last erzeugt die sowohl Prozessor als auch

    die Festplatte abhält in einen Ruhemodus zu gehen. Beim Prozessor nicht dass Problem aber bei vor allem mechanischen Festplatten ein größeres Manko gegenüber der Event-Methode.

    Weiterer Vorteil: du sparst dir die selbst zu schreibende Analyse was sich genau wie geändert hat. Mit der Event-Lösung bekommst du direkt die Info ob z.b. eine Datei umbenannt wurde. Ein naiver selbst geschriebener Ansatz würde bei sowas eher davon ausgehen dass eine Datei gelöscht wurde und eine andere dazu gekommen ist.

  • Gegen meine Lösung mit if FileExists oder FileFindFirstFile spricht schon mal, dass ein großes File bereits mit Beginn des Schreibvorganges als

    vorhanden erkannt wird. Ein 1gig File existiert für Autoit bereits obwohl Windows das File noch nicht fertig geschrieben hat.

    Da stellt sich eigentlich schon mal die Frage Bug oder Feature? Für mich sollte ein File erst existieren wenn es auch wirklich "vorliegt"

    Hinweise auf Suchmaschinen finde ich überflüssig - wer fragt hat es nicht gefunden oder nicht verstanden. Die Antwort gibt sich oftmals schneller als der Hinweis auf Dr. Goggle & Co.

    Ab 19-10-22 ergänzt um:

    Die Welt wird nicht bedroht von den Menschen, die böse sind, sondern von denen, die das Böse zulassen. (Albert Einstein)

    • Offizieller Beitrag

    Da stellt sich eigentlich schon mal die Frage Bug oder Feature? Für mich sollte ein File erst existieren wenn es auch wirklich "vorliegt"

    Ich denke, dass das kein Bug ist, denn die Datei existiert ja bereits. FileExists macht somit genau das, was der Befehl aussagt.

    Bei der Event-Methode werden beim kopieren einer Datei deswegen auch zwei Events ausgelöst. Einmal $SHCNE_CREATE und dann $SHCNE_UPDATEITEM.

  • Danke für den Hinweis.

    Aspirinjunky benutzt in seinem Script eine Endlosschleife

    Do

    sleep(100)

    until 0

    Wie muss ich mir das vorstellen, dass die Schleife "überwunden wird? Nachmeinem Verständnis laüft Autoit stundenlang in dieser Schleife. Aber Func ReactOnEvents(Const $hWndGUI, Const $MsgID, Const $wParam, Const $lParam) wird ja aufgerufen. Wie muss ich mir das vorstellen? Sorry wenn die Frage naiv ist ... aber da klemmt es in meiner Vorstellung?

    Danke Peter


    #Region ShellEvent registrieren

    Global $h_GUI = GUICreate("test")

    Global $h_Msg = _WinAPI_RegisterWindowMessage('irgendwas') ; Die Message "irgendwas" wird an das Fenster $h_GUI gesendet wenn ein Event auftritt

    GUIRegisterMsg($h_Msg, 'ReactOnEvents')

    Global $h_ShellNotify1 = _WinAPI_ShellChangeNotifyRegister($h_GUI, $h_Msg, $SHCNE_ALLEVENTS, 0x3, $s_PATH)

    #EndRegion ShellEvent registrieren

    Do

    Sleep(100)

    Until 0 ; das ist eine endlosschleife

    ; Funktion die aufgerufen wird wenn ein Event auftritt:

    Func ReactOnEvents(Const $hWndGUI, Const $MsgID, Const $wParam, Const $lParam)

    Local $s_PATH = DllCall("Shell32.dll", "BOOLEAN", "SHGetPathFromIDListW", "ptr", DllStructCreate("PTR A; PTR", $wParam).A, "wstr", "")[2]

    Hinweise auf Suchmaschinen finde ich überflüssig - wer fragt hat es nicht gefunden oder nicht verstanden. Die Antwort gibt sich oftmals schneller als der Hinweis auf Dr. Goggle & Co.

    Ab 19-10-22 ergänzt um:

    Die Welt wird nicht bedroht von den Menschen, die böse sind, sondern von denen, die das Böse zulassen. (Albert Einstein)

  • Wie muss ich mir das vorstellen, dass die Schleife "überwunden wird?

    Dein Script läuft in die Schleife damit es sich nicht beendet und das Event wird dann ausgeführt. Wie genau was blockiert wird kann ich dir auf Anhieb nicht sagen, aber du kannst es ja mit einfachen Schleifen und ConsoleWrites mal testen und uns berichten. Generell sollte man in Events (sowie in AdlibFunktionen und Hotkeys) keine blockierenden Funktionen wie MsgBox oder ähnliches verwenden.

  • Wiedermal habe ich es nicht geschafft mein Problem darzulegen ;(. Das mit der Schleife war mir schon klar. Die ist da damit das Programm kein ende findet. Nur ist vor der Schleife ein:

    GUIRegisterMsg($h_Msg, 'ReactOnEvents') was zu deutsch bedeutet wenn ein "Event" eintritt wird die Funktion ReactonEvent aufgerufen, die Funktion steht aber nach der Schleife. Nun verstehe ich nicht wie Autoit in einer Schleife festhängt, und trotzdem die Funktion ausführt?

    1.png


    Mag sein, dass mein Verständnisproblem eine Lachnummer ist - ok damit muss ich dann wohl leben. Trotzdem bin ich dankbar für den passenden Anstoß

    Danke

    Peter

    Hinweise auf Suchmaschinen finde ich überflüssig - wer fragt hat es nicht gefunden oder nicht verstanden. Die Antwort gibt sich oftmals schneller als der Hinweis auf Dr. Goggle & Co.

    Ab 19-10-22 ergänzt um:

    Die Welt wird nicht bedroht von den Menschen, die böse sind, sondern von denen, die das Böse zulassen. (Albert Einstein)

  • Das ist so ziemlich das selbe, als ob du innerhalb der Schleife einen eigenen Funktionsaufruf machen würdest. Das eintretende Event führt automatisch zu einem JUMP zur definierten Funktion und danach gehts wieder dort weiter wo unterbrochen wurde. Das selbe Prinzip wird bei der Funktion adlibregister oder hotkeyset angewandt.

    Beispiel mit Hotkeyset:

    Jenachdem wann du ESC drückst wird das Script entweder innerhalb der Hauptschleife oder aber innerhalb deiner eigenen Funktion für die Ausführung der Eventfunktion unterbrochen.

    2 Mal editiert, zuletzt von misterspeed (10. Dezember 2017 um 08:00)

  • misterspeed

    Danke das habe ich, mit Deiner Erklärung verstanden.

    Nun stellt sich, begründet mit Deiner Antwort bereits die nächst Frage:

    Du schreibst:

    ....Jenachdem wann du ESC drückst wird das Script entweder innerhalb der Hauptschleife oder aber innerhalb deiner eigenen Funktion für die Ausführung der Eventfunktion unterbrochen.......

    Bedeuted das, dass auch beim Auftauchen neuer Files die Ausführung meiner Funktion unterbrochen wird? Ich gehe mal von ja aus? Das allerdings würde für die Überwachung von Foldern, bzw. der Verarbeitung der Dateien weitreichende Folgen haben...

    Wenn ich, nachdem eine File gemeldet wurde - in die Verarbeitung eintrete und diese dann vom Event (neues File) unterbrochen wird, ist an eine geordnete "Stapelverarbeitung" nicht zu denken....

    Auch bietet sich ein runwait zu externen Funktionen nicht an?

    Liege ich da richtig?


    Danke für Eure Hilfe

    Peter

    Hinweise auf Suchmaschinen finde ich überflüssig - wer fragt hat es nicht gefunden oder nicht verstanden. Die Antwort gibt sich oftmals schneller als der Hinweis auf Dr. Goggle & Co.

    Ab 19-10-22 ergänzt um:

    Die Welt wird nicht bedroht von den Menschen, die böse sind, sondern von denen, die das Böse zulassen. (Albert Einstein)

  • Jenachdem wie du dein Script aufgebaut hast kann das durchaus zu Problemen führen. Deswegen macht in meinem Script die Eventfunktion lediglich einen neuen Eintrag in einem Array. In der Hauptschleife wird dann geprüft ob unbearbeitete Dateien im Array vermerkt sind und diese werden dann nacheinander abgearbeitet.

    EDIT: Ob runwait unterbrechbar ist kann ich dir nicht sagen. Die langen Sleeps oben im Beispielscript werden aber scheinbar unterbrochen, da man ESC sehr schnell in Folge drücken kann. Aber selbst wenn auch runwait unterbrochen werden kann ist das kein Problem wenn du wie oben beschrieben vorgehst.

  • misterspeed.

    Bleibt das nicht trotzdem ein Henne Ei Problem? Vielleicht fehlt mir das Verständnis oder ich sehe Gespenster. Aber auch das Array/File mit den gespeicherten Dateinamen muss abgearbeitet werden, der Breack des Eventes kommt immer dazwischen. Eigentlich müsste man den Event abschalten. Ich betrachte das so:

    Der Event benachrichtigt - ein File ist eingetroffen. Nun will ich dies zügig verarbeiten. Ich würde das - auf keinen Fall im überwachten Ordner machen. Also lößt der Event zuersteinmal eine Deaktivierung von sich selbst aus - danach ein File Move....

    Dann die Verarbeitung, Danach Überwachungsevent wieder einschalten. Das einzige Problem sind die Files die ev. in der eventpause eingetroffen sind... die flutschen durch. Hmmmm...

    Würde dieses permanente Event ein/ aus ein Problem bedeuten? Oder verstehe ich die Geschichte mit dem Event nicht richtig?

    Danke

    Peter

    Hinweise auf Suchmaschinen finde ich überflüssig - wer fragt hat es nicht gefunden oder nicht verstanden. Die Antwort gibt sich oftmals schneller als der Hinweis auf Dr. Goggle & Co.

    Ab 19-10-22 ergänzt um:

    Die Welt wird nicht bedroht von den Menschen, die böse sind, sondern von denen, die das Böse zulassen. (Albert Einstein)

  • Hallo Peter S. Taler,

    probiere es doch einfach mal mit dem Event wie beschrieben aus. Wenn beim Event nicht mehr passiert, als das die Datei in einem Array erfasst wird, verstehe ich nicht, welche Probleme auftauchen sollten. Das geht doch nullkommanix und macht nichts an deinem Abarbeiten kaputt.

    Grüße autoiter

  • Seh jetzt auch nicht das Problem darin. Ja dein Array könnte aufgrund weiterer Events während der Abarbeitung der zuvor erfassten Datei(en) aktualisiert werden. Warum sollte das Konsequenzen haben? Wenn deine Funktion nicht damit klar kommt, wenn weitere Dateien im Array auftauchen dann arbeite mit einer Kopie des "alten" Standes als die Funktion aufgerufen wurde. Alle weiteren Dateien kommen dann erst zum Tragen wenn deine Endlosschleife erneut Dateien im Array vorfindet und die Abarbeitung ein weiteres Mal aufruft. Alternativ gibst du immer nur den Dateinamen einer Datei an die Abarbeitungsfunktion heraus (siehe unten).

    Beispiel:

    EDIT:

    Wie du selbst festgestellt hast ist das Event Abschalten keine Lösung, denn dann würdest du neue Dateien evtl. verpassen.

  • Hatte nie Probleme mit multiplen Events.
    Auch wenn ich es nicht garantiert weiß glaube ich zu wissen dass diese in ein Stack geschmissen werden und dort schrittweise abgearbeitet werden.
    Heißt: Die Bearbeitung von Events wird nicht verschluckt sondern verzögert.

  • @ aspirinjunky,

    ich habe folgendes probiert, ich habe eine msg Box eingebaut (in Deinem Sript, dort wo Du die Verzweigung zu eigenen Funktionen vorschlägst). Funktion gestartet, Datei eingefügt msg Box geht auf, noch ne Datei eingefügt, solange die Msg Box nicht geschlossen wird, taucht die Datei im Explorer Fenster nicht auf. Wartet man, mit geöffneter Msg Box eine geraume Zeit, scheint im Event ein Timeout statt zu finden, denn die Datei taucht im Explorer Fenster auf, Ein Event wird nicht ausgeführt.

    Gleichermaßen iritiert mich, dass man, an gleicher Stelle, ein _FileListToArray einbauen kann, ein nachgeschaltetes _ArrayDisplay aber scheitert (Fenster bekommt keinen Inhalt).

    Ansonsten werde ich Eure Ratschläge mal umsetzen, also meine Bedenken zu Seite schieben, und weiter probieren.

    Peter

    Hinweise auf Suchmaschinen finde ich überflüssig - wer fragt hat es nicht gefunden oder nicht verstanden. Die Antwort gibt sich oftmals schneller als der Hinweis auf Dr. Goggle & Co.

    Ab 19-10-22 ergänzt um:

    Die Welt wird nicht bedroht von den Menschen, die böse sind, sondern von denen, die das Böse zulassen. (Albert Einstein)