web-dev-qa-db-fra.com

Comment surveiller un dossier et déclencher une action de ligne de commande lorsqu'un fichier est créé ou modifié?

Je dois configurer une sorte de script sur ma machine Vista afin que, chaque fois qu'un fichier est ajouté à un dossier particulier, il déclenche automatiquement un processus en arrière-plan qui fonctionne sur le fichier. (Le processus d'arrière-plan est simplement un utilitaire de ligne de commande qui prend le nom du fichier en argument, ainsi que d'autres options prédéfinies.)

Je souhaiterais utiliser des fonctionnalités Windows natives, si possible, pour des raisons de performances et de maintenance. J'ai envisagé d'utiliser le Planificateur de tâches, mais après avoir parcouru le système de déclenchement pendant un moment, je n'ai pas été en mesure de le comprendre, et je ne suis même pas sûr qu'il soit capable de faire ce dont j'ai besoin.

J'apprécierais toutes les suggestions. Merci!

75
bigmattyh

Merci à tous pour les suggestions.

J'ai fini par écrire un script VBScript basé sur l'idée de Linker3000 consistant à interroger le dossier et à utiliser le Planificateur de tâches pour l'exécuter au démarrage. J'ai fini par obtenir la syntaxe de base de cette ressource et faire les ajustements nécessaires.

J'aimerais quand même l'optimiser à un moment donné, en laissant le courage du script s'exécuter sur un système piloté par les événements, mais je n'ai plus beaucoup de temps pour travailler dessus, et bien, c'est assez bon.

Voici le script, au cas où quiconque serait intéressé (avec le segment de conversion non pertinent rédigé pour des raisons de clarté):

' 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

(En outre, je ne veux pas laisser cette question officiellement sans réponse - et je déteste accepter ma propre réponse à la question - mais j'ai voté en faveur de la réponse de Linker3000 en guise de remerciement!)

3
bigmattyh

Au travail, nous utilisons Powershell pour surveiller les dossiers.
Il peut être utilisé depuis Windows Vista (pré-installé avec .NET et PowerShell) sans aucun outil supplémentaire.

Ce script surveille un certain dossier et écrit un fichier journal. Vous pouvez remplacer l'action et faire ce que vous voulez, par exemple appeler un outil externe

Exemple de fichier journal

 23/11/2014 19:22:04, créé, D:\source\Nouveau document texte.txt 
 23/11/2014 19:22:09, modifié, D:\source\New Text Document.txt 
 23/11/2014 19:22:09, Modifié, D:\source\New Text Document.txt 
 11/23/2014 19:22:14, Supprimé, D:\source\Nouveau document texte.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}

Comment utiliser

  1. Créer un nouveau fichier texte
  2. Copier et coller le code ci-dessus
  3. Modifiez les paramètres suivants selon vos propres besoins:
    • dossier à surveiller: $watcher.Path = "D:\source"
    • filtre de fichier pour inclure uniquement certains types de fichiers: $watcher.Filter = "*.*"
    • inclure les sous-répertoires oui/non: $watcher.IncludeSubdirectories = $true
  4. Enregistrez-le et renommez-le en StartMonitoring.ps1
  5. Démarrer la surveillance par Clic droit »Exécuter avec PowerShell

Pour arrêter la surveillance, il suffit de fermer la fenêtre de PowerShell.

Lectures complémentaires

85
nixda

Vous semblez être sur les bonnes lignes - vous pouvez utiliser le planificateur de tâches pour exécuter régulièrement un fichier .bat ou .cmd et ce fichier peut commencer par une ligne pour vérifier l'existence du fichier requis - en fait, je 'vérifierais la non-existence du fichier; par exemple:

@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

Vous pouvez également modifier ce code et le faire exécuter en boucle avec un délai d'une minute, par exemple, puis mettre une référence au fichier de commandes dans le dossier de démarrage de Windows:

@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

Il existe d'autres moyens d'obtenir un délai en fonction de la version de Windows utilisée et des kits de ressources supplémentaires installés, mais la commande PING fonctionne quasiment dans toutes les circonstances. Dans la commande PING ci-dessus, 10 PINGGES fantômes sont exécutés avec un délai de 6 000 ms (soit 6 secondes) entre eux. Vous pouvez utiliser ces valeurs pour obtenir le délai nécessaire entre les boucles de traitement par lots.

5
Linker3000

Si l’action consiste uniquement à copier les fichiers modifiés, vous pouvez utiliser robocopy/MON.

Je ne sais pas si robocopy utilise FileSystemWatcher ou fonctionne en interrogeant les modifications

2
weberjn

Vous pourriez regarder DropIt (gratuit). Le programme convient au traitement des fichiers entrants de manière automatisée. Vous pouvez déplacer, copier, supprimer et transmettre des paramètres à d'autres programmes en ligne de commande pour convertir des images, des PDF divisés, etc.

1
Sun

Ou vous pouvez utiliser Watch 4 Folder . Apparemment, c'est Freeware, portable et compatible avec Windows 7. Je ne l'ai pas essayé, mais je l'ai trouvé grâce à une recherche sur le Web et j'ai pensé le transmettre.

J'aime aussi le script VBS, également présenté sur le site.

1
Chris

Aussi trouvé gardien qui semble être assez grand, et un plus petit watchexec je n'ai pas essayé.

1
Pysis

Nous utilisons l’outil commercial (c’est-à-dire pas gratuit). Sondage de dossier à partir de http://www.myassays.com/folder-poll pour ce faire. C'est une application Windows qui inclut une application de gestion conviviale pour permettre une configuration facile. Il existe également une option de configuration XML. La scrutation des dossiers s’effectue en tant que service Windows (elle démarre donc automatiquement à chaque redémarrage). Lorsqu'un nouveau fichier est détecté dans un dossier interrogé, une application peut être lancée automatiquement (vous pouvez spécifier vos propres arguments de ligne de commande personnalisés). Il peut aussi faire d’autres choses comme copier/déplacer des fichiers. En outre, l'activité peut être consignée dans un fichier journal et il existe d'autres opérations avancées.

0
Mister Cook