crashzero
Goto Top

Filewatcher Loop

Moin,

ich benötige eine Ordnerüberwachung wie folgt :
Ein Verzeichnis wird rekursiv auf Dateieingänge überwacht.
Kommen Dateien dort in diversen Verzeichnissen an, soll das Script die Dateien zählen UND wenn länger als 5 Sekunden keine Dateianzahländerung mehr stattfindet, soll er den FileSystemWatcher "entladen" und die Schleife beenden damit dann weitere Aktionen erfolgen können.

Ich arbeite grad an diesem Script aber leider wartet er das Übermittlungsende (Also 5 Sekunden lang keine weitere Datei dazugekommen) ab.

Hat jemand eine Idee :

# Pfad zum zu überwachenden Verzeichnis
$verzeichnis = "C:\Verzeichnis\Ueberwachungsverzeichnis\"  

# Erstelle einen FileSystemWatcher für das Verzeichnis
$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = $verzeichnis

# Aktiviere die Überwachung von Dateiänderungen
$watcher.EnableRaisingEvents = $true

# Festlegen der Ereignisse, die überwacht werden sollen
$watcher.IncludeSubdirectories = $false
$watcher.NotifyFilter = [System.IO.NotifyFilters]::FileName -bor [System.IO.NotifyFilters]::LastWrite

# Initialisiere die Variable für die Dateizählung
$dateiZaehler = 0

# Initialisiere den Zeitpunkt der letzten Änderung
$letzteAenderung = Get-Date

# Timer für 5 Sekunden
$timer = New-Object System.Timers.Timer
$timer.Interval = 5000 # 5000 Millisekunden = 5 Sekunden

# Definiere die Aktion, die bei jeder Änderung ausgeführt wird
$action = {
    # Zähle die Anzahl der Dateien im Verzeichnis
    $dateiAnzahl = (Get-ChildItem -Path $verzeichnis -File).Count

    # Überprüfe, ob die Anzahl der Dateien seit 5 Sekunden gleich ist
    if ($dateiAnzahl -eq $dateiZaehler) {
        $vergangeneZeit = (Get-Date) - $letzteAenderung
        if ($vergangeneZeit -ge [TimeSpan]::FromSeconds(5)) {
            Write-Host "Die Anzahl der Dateien ist seit 5 Sekunden gleich. Beende die Schleife."  
            $timer.Stop()  # Stoppe den Timer
            $timer.Dispose()  # Gib die Timer-Ressourcen frei
            $watcher.EnableRaisingEvents = $false  # Deaktiviere die Überwachung
        }
    } else {
        # Aktualisiere den Zähler und den Zeitpunkt der letzten Änderung
        $dateiZaehler = $dateiAnzahl
        $letzteAenderung = Get-Date
    }
}

# Füge die Aktion dem Ereignis "Changed" hinzu 
Register-ObjectEvent -InputObject $watcher -EventName Changed -Action $action -SourceIdentifier FileSystemWatcherEvent

# Starte den Timer
$timer.Start()

# Starte eine Endlosschleife, um das Skript am Laufen zu halten
while ($watcher.EnableRaisingEvents) {
    Start-Sleep -Milliseconds 500  # Kurze Pause, um die CPU-Last zu reduzieren
}

# Entferne den FileSystemWatcher und den Timer, wenn das Skript beendet wird
Unregister-Event -SourceIdentifier FileSystemWatcherEvent -Force

Content-Key: 3595890485

Url: https://administrator.de/contentid/3595890485

Printed on: May 1, 2024 at 09:05 o'clock

Member: emeriks
emeriks Dec 19, 2023 at 15:03:36 (UTC)
Goto Top
Hi,
ich glaube, Du hast hier die Funktion des Timers mißverstanden. Das ist kein "Wait" oder "Pause". Der Timer macht nur Sinn, wenn man dessen Event "Elapsed" auswertet.

Statt des Timers solltest Du eine Variable "$StopLoop" o.ä. erstellen mit "$false" als Standard.
Im $action-Block setzt Du $StopLoop auf $true, wo Du jetzt $timer.stop() ausführst.

Statt des $timer.Start() lässt Du ein while laufen
while(-not $StopLoop) {
  Start-Sleep -Milliseconds 500
}

Allerdings:
Wenn keine Datei mehr geändert wird, dann wird auch der $action-Block nicht mehr ausgeführt und die Schleife wird nie enden.
Irgendwo stimmt da Deine Logik nicht, oder ich habe diese nicht verstanden.

E.
Member: Crashzero
Crashzero Dec 20, 2023 at 06:53:17 (UTC)
Goto Top
Hy,
doch genau das ist richtig.
Das ist eine Anwendung die nie endet.
Es findet eine dauerhafte Prüfung auf Dateieingang statt, innerhalb dieser ev. While-Scheife findet dann natürlich noch sehr viel mehr statt.
Er soll durchaus dauerhaft "geschliffen" sein.
Member: emeriks
emeriks Dec 21, 2023 at 13:46:40 (UTC)
Goto Top
Aber dann fehlt dafür die äußere Schleife.
Member: Crashzero
Crashzero Dec 21, 2023 at 17:52:27 (UTC)
Goto Top
Ja, die ist schnell gesetzt.
Das ganze ist ja nur ein Auszug aus einem ganzen.

Hab das jetzt so gelöst:
FileWatcher achtet auf den Eingang einer Datei dann wird der FileWatcher verlassen und es geht ab in eine Dateizählschleife.Dort werden die Dateien gezählt die weiterhin ankommen oder auch nicht und wenn ca.5 Sekunden kein Dateieingang mehr zu verzeichnen ist wird der Empfang blockiert und die eingegangenen Dateien verarbeitet.
Funktioniert super.