Wie kann ich einen Ordner überwachen und eine Befehlszeilenaktion auslösen, wenn eine Datei erstellt oder bearbeitet wird?

82

Ich muss auf meinem Vista-Computer eine Art Skript einrichten, damit beim Hinzufügen einer Datei zu einem bestimmten Ordner automatisch ein Hintergrundprozess ausgelöst wird, der auf die Datei angewendet wird. (Der Hintergrundprozess ist nur ein Befehlszeilenprogramm, das den Dateinamen zusammen mit einigen anderen vordefinierten Optionen als Argument verwendet.)

Ich möchte dies aus Leistungs- und Wartungsgründen mit systemeigenen Windows-Funktionen tun, sofern dies möglich ist. Ich habe mich mit der Verwendung von Task Scheduler befasst, aber nachdem ich das Triggersystem eine Weile durchgesehen habe, konnte ich nicht viel daraus lernen und bin mir nicht einmal sicher, ob es in der Lage ist, das zu tun, was ich brauche.

Ich würde mich über Vorschläge freuen. Vielen Dank!

bigmattyh
quelle
Klingt so, als ob Sie etwas wie Linux inotify benötigen, aber für Windows. Jnotify könnte helfen, aber da es Java ist, könnte es zu schwer sein.
Keith
1
Ich habe mich auch darüber gewundert ... habe die [MSDN-Seite] gefunden ( msdn.microsoft.com/en-us/library/aa365261(VS.85).aspx) .
Keith

Antworten:

92

Bei der Arbeit verwenden wir Powershell, um Ordner zu überwachen.
Es kann seit Windows Vista (.NET und PowerShell sind vorinstalliert) ohne zusätzliche Tools verwendet werden.

Dieses Skript überwacht einen bestimmten Ordner und schreibt eine Protokolldatei. Sie können die Aktion ersetzen und tun, was Sie möchten, z. B. ein externes Tool aufrufen

Beispielprotokolldatei

23.11.2014 19:22:04, Erstellt, D: \ source \ New Text Document.txt
23.11.2014 19:22:09, Geändert, D: \ source \ New Text Document.txt
23.11.2014 19:22:09, Geändert, D: \ source \ New Text Document.txt
23.11.2014 19:22:14, Gelöscht, D: \ source \ New Text Document.txt

StartMonitoring.ps1

### SET FOLDER TO WATCH + FILES TO WATCH + SUBFOLDERS YES/NO
    $watcher = New-Object System.IO.FileSystemWatcher
    $watcher.Path = "D:\source"
    $watcher.Filter = "*.*"
    $watcher.IncludeSubdirectories = $true
    $watcher.EnableRaisingEvents = $true  

### DEFINE ACTIONS AFTER AN EVENT IS DETECTED
    $action = { $path = $Event.SourceEventArgs.FullPath
                $changeType = $Event.SourceEventArgs.ChangeType
                $logline = "$(Get-Date), $changeType, $path"
                Add-content "D:\log.txt" -value $logline
              }    
### DECIDE WHICH EVENTS SHOULD BE WATCHED 
    Register-ObjectEvent $watcher "Created" -Action $action
    Register-ObjectEvent $watcher "Changed" -Action $action
    Register-ObjectEvent $watcher "Deleted" -Action $action
    Register-ObjectEvent $watcher "Renamed" -Action $action
    while ($true) {sleep 5}

Wie benutzt man

  1. Erstellen Sie eine neue Textdatei
  2. Kopieren Sie den obigen Code und fügen Sie ihn ein
  3. Ändern Sie die folgenden Einstellungen nach Ihren Wünschen:
    • zu überwachender Ordner: $watcher.Path = "D:\source"
    • Dateifilter, um nur bestimmte Dateitypen einzuschließen: $watcher.Filter = "*.*"
    • Unterverzeichnisse einbeziehen ja / nein: $watcher.IncludeSubdirectories = $true
  4. Speichern und benennen Sie es in um StartMonitoring.ps1
  5. Starten Sie die Überwachung mit einem Rechtsklick auf »Mit PowerShell ausführen

Um die Überwachung zu beenden, muss lediglich das PowerShell-Fenster geschlossen werden

Weitere Lektüre

Nixda
quelle
Funktioniert gut, aber was ist die Funktion des Stopp-Skripts? Ich erhalte Fehler: "Unregister-Event: Das Argument kann nicht an den Parameter 'SourceIdentifier' gebunden werden, da es null ist." pastebin.com/ugLB3a69
Jan Stanstrup
@ JanStanstrup Ich habe wahrscheinlich mehr Leute mit dem zweiten Drehbuch verwechselt. Ich werde es löschen. Es reicht aus, einfach das StartWatching.ps1Fenster zu schließen, um die Überwachung zu stoppen. Das zweite Skript funktioniert nur , wenn Sie es in Ihrem ersten Skript enthalten die Variablen zu speichern $created, $changed, $deletedoder$renamed
nixda
Danke für die Antwort. Kann jemand vorschlagen, ob wir Cmd-Eingabeaufforderung verwenden könnten, da ich die Dateien zu Github hochladen möchte, wenn geändert
m__
5

Sie scheinen auf dem richtigen Weg zu sein - Sie könnten den Taskplaner verwenden, um regelmäßig eine .bat- oder .cmd-Datei auszuführen, und diese Datei könnte mit einer Zeile beginnen, um zu überprüfen, ob die erforderliche Datei vorhanden ist würde überprüfen, ob die Datei nicht existiert; zum Beispiel:

@ECHO OFF
REM Example file
IF NOT EXIST C:\SOMEWHERE\SUBFOLDER\THISFILE.THS EXIT 1
REM All this gets done if the file exists...
:
:
EXIT 0

Sie können diesen Code auch ändern und ihn in einer Schleife mit einer Verzögerung von beispielsweise 1 Minute ausführen lassen und dann einen Verweis auf die Batchdatei in den Windows-Startordner einfügen:

@ECHO OFF
REM Example file
:LOOP    
IF NOT EXIST C:\SOMEWHERE\SUBFOLDER\THISFILE.THS GOTO SKIP01
REM All this gets done if the file exists...
:
:
:SKIP01
REM Crafty 1 minute delay...
PING 1.1.1.1 -n 10 -w 6000 >NUL
GOTO LOOP

Es gibt andere Möglichkeiten, eine Verzögerung zu erzielen, die von der ausgeführten Windows-Version und den installierten zusätzlichen Resource Kits abhängt. Der Befehl PING funktioniert jedoch unter allen Umständen. Im obigen PING-Befehl werden 10 Phantom-PINGS mit einer Verzögerung von 6000 ms (dh 6 Sekunden) zwischen ihnen ausgeführt. Sie können mit diesen Werten spielen, um die Verzögerung zu erreichen, die Sie zwischen Batch-Dateischleifen benötigen.

Linker3000
quelle
nette Idee .. übrigens, C: \> Ping 1.1.1.1 -n 10 -w 6000 aus irgendeinem Grund dauerte 1 Minute 10 Sekunden auf meinem Computer. Aber -n 1 -w 60000 hat genau 1 Minute gedauert.
Barlop
@barlop - Die zehn Sekunden lange Diskrepanz ist auf die -n 10vs zurückzuführen -n 1.
@Randolph Potter Sind das nicht 10 Lose von 6 Sekunden, 60 Sekunden? und -n 10, die Sie verwenden, sollte 10-mal bedeuten.
Barlop
Du hast wahrscheinlich Recht. Ich nehme es zurück und beschuldige mein blondes Haar.
Am Ende habe ich diese Schleife für eine Überwachungsreihe verwendet IF NOT EXIST C:\NO_SUCH_FILE_EVER.foo. Hackish, aber es funktioniert. Danke für die Idee.
Snekse
3

Vielen Dank für die Vorschläge.

Am Ende habe ich ein VBScript geschrieben, das in etwa auf der Idee von Linker3000 basierte, den Ordner abzufragen und mit dem Taskplaner beim Start auszuführen. Ich erhielt die grundlegende Syntax aus dieser Ressource und nahm die erforderlichen Optimierungen vor.

Ich würde es gerne noch irgendwann optimieren, wenn die Eingeweide des Skripts auf einem ereignisgesteuerten System laufen würden, aber mir fehlt die Zeit, um daran zu arbeiten, und das ist gut genug.

Hier ist das Skript, falls sich jemand dafür interessiert (wobei das irrelevante Konvertierungssegment aus Gründen der Übersichtlichkeit überarbeitet wurde):

' FOLDER TO MONITOR
strFolder = "J:\monitored-folder"

' FREQUENCY TO CHECK IT, IN SECONDS
nFrequency = 10

strComputer = "."
strQueryFolder = Replace(strFolder, "\", "\\\\")
Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" &     strComputer & "\root\cimv2") 
Set colMonitoredEvents = objWMIService.ExecNotificationQuery ("SELECT * FROM __InstanceCreationEvent WITHIN " & nFrequency & " WHERE Targetinstance ISA 'CIM_DirectoryContainsFile' and TargetInstance.GroupComponent='Win32_Directory.Name=""" & strQueryFolder & """'") 

Do 
    Set objLatestEvent = colMonitoredEvents.NextEvent
    strNewFile = objLatestEvent.TargetInstance.PartComponent
    arrNewFile = Split(strNewFile, "=")
    strFilePath = arrNewFile(1)
    strFilePath = Replace(strFilePath, "\\", "\")
    strFilePath = Replace(strFilePath, Chr(34), "")
    strFileName = Replace(strFilePath, strFolder, "")
    strTempFilePath = WScript.CreateObject("Scripting.FileSystemObject").GetSpecialFolder(2) & "\TEMP.M4A"

    ' DO THE OPERATION STUFF
    ' ...
Loop

(Außerdem möchte ich diese Frage nicht offiziell unbeantwortet lassen - und ich hasse es, meine eigene Antwort auf die Frage zu akzeptieren -, aber ich habe die Antwort von Linker3000 zum Dank positiv bewertet!)

bigmattyh
quelle
2

Sie könnten sich DropIt (kostenlos) ansehen . Das Programm eignet sich zum automatisierten Verarbeiten eingehender Dateien. Sie können Parameter verschieben, kopieren, löschen und an andere Befehlszeilenprogramme übergeben, um Bilder zu konvertieren, PDFs zu teilen usw.

Sonne
quelle
2

Wenn nur geänderte Dateien kopiert werden sollen, können Sie robocopy / MON verwenden

Ich weiß nicht, ob robocopy FileSystemWatcher verwendet oder nach Änderungen fragt

weberjn
quelle
1

Oder Sie könnten Watch 4 Folder verwenden . Anscheinend ist es Freeware, portabel und kompatibel mit Windows 7. Ich habe es noch nicht ausprobiert, es aber über eine Websuche gefunden und dachte, ich würde es weitergeben.

Ich mag auch das VBS-Skript, das auch auf der Website vorgestellt wird.

Chris
quelle
Leider ist nur die kostenpflichtige Version portabel
nixda
Dachte darüber nach, diese Software zu verwenden. Würden Sie darauf vertrauen, dass eine Netzwerkfreigabe mit wichtigen Dateien von vielen Benutzern überwacht wird?
Paul Matthews
Die kostenlose Version von Watch4Folder hat nur einen "Beispiel" -Eintrag, der konfiguriert werden kann.
PeterCo
1

Auch gefunden Wächter , die ziemlich groß, und ein kleiner zu sein scheint watchexec ich versucht habe , nicht.

Pysis
quelle
0

Wir verwenden das kommerzielle Tool (dh nicht kostenlos) Folder Poll von http://www.myassays.com/folder-poll , um genau dies zu tun. Es ist eine Windows-Anwendung, die eine benutzerfreundliche Manager-Anwendung enthält, um eine einfache Konfiguration zu ermöglichen. Es gibt auch eine XML-Konfigurationsoption. Die eigentliche Ordnerabfrage wird als Windows-Dienst ausgeführt (wird also bei jedem Neustart automatisch gestartet). Wenn eine neue Datei in einem abgefragten Ordner gefunden wird, kann eine Anwendung automatisch gestartet werden (Sie können Ihre eigenen benutzerdefinierten Befehlszeilenargumente angeben). Es kann auch andere Dinge wie das Kopieren / Verschieben von Dateien erledigen. Die Aktivität kann auch in einer Protokolldatei protokolliert werden, und es gibt andere erweiterte Vorgänge.

Herr Koch
quelle