2010-12-29 08:06:29 +0000 2010-12-29 08:06:29 +0000
87
87

¿Cómo supervisar una carpeta y activar una acción de la línea de comandos cuando se crea o edita un archivo?

Necesito configurar algún tipo de script en mi equipo de Vista, de modo que cada vez que se agregue un archivo a una carpeta en particular, se active automáticamente un proceso de fondo que opere sobre el archivo. (El proceso de fondo es sólo una utilidad de la línea de comandos que toma el nombre del archivo como argumento, junto con algunas otras opciones predefinidas)

Me gustaría hacer esto usando características nativas de Windows, si es posible, por razones de rendimiento y mantenimiento. He investigado el uso del Programador de Tareas, pero después de examinar el sistema disparador durante un tiempo, no he podido encontrarle mucho sentido, y ni siquiera estoy seguro de que sea capaz de hacer lo que necesito.

Agradecería cualquier sugerencia. Gracias.

Respuestas (8)

96
96
96
2014-11-23 18:26:49 +0000

En el trabajo usamos Powershell para monitorear carpetas. Puede ser usado desde Windows Vista (.NET y PowerShell está preinstalado) sin ninguna herramienta adicional.

Este script monitorea una cierta carpeta y escribe un archivo de registro. Puede reemplazar la acción y hacer lo que desee, por ejemplo, llamar a una herramienta externa

Archivo de registro de ejemplo

11/23/2014 19:22:04, Created, D:\source\New Text Document.txt 11/23/2014 19:22:09, Changed, D:\source\New Text Document.txt 11/23/2014 19:22:09, Changed, D:\source\New Text Document.txt 11/23/2014 19:22:14, Deleted, 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}

Cómo usar

  1. Crear un nuevo archivo de texto
  2. Copie y pegue el código anterior
  3. Cambie los siguientes ajustes a sus propias necesidades:
  4. carpeta a monitorizar: $watcher.Path = "D:\source"
  5. filtro de archivos para incluir sólo ciertos tipos de archivos: $watcher.Filter = "*.*"
  6. incluir subdirectorios sí/no: $watcher.IncludeSubdirectories = $true
  7. Guardar y renombrar a StartMonitoring.ps1
  8. Iniciar el monitoreo con Clicks derechos “ Ejecutar con PowerShell

Para detener el monitoreo, es suficiente con cerrar la ventana de PowerShell

Lectura adicional

6
6
6
2010-12-29 08:49:30 +0000

Parece que estás en la línea correcta - podrías usar el programador de tareas para ejecutar un .bat o . cmd de forma regular y ese archivo podría comenzar con una línea para comprobar la existencia del archivo requerido - de hecho, comprobaría la no existencia del archivo; por ejemplo:

@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

También podría modificar este código y hacer que se ejecute en un bucle con un, digamos, 1 minuto de retraso en el bucle y luego poner una referencia al archivo por lotes en la carpeta de inicio 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

Hay otras formas de lograr un retraso según la versión de Windows que se esté ejecutando y qué kits de recursos adicionales se hayan instalado, pero el comando PING funciona prácticamente en todas las circunstancias. En el comando PING de arriba, se ejecutan 10 PINGS fantasmas con un retraso de 6000ms (es decir, 6 segundos) entre ellos, puedes jugar con estos valores para lograr el retraso que necesitas entre los bucles de archivos por lotes.

4
4
4
2011-01-07 04:01:48 +0000

Gracias a todos, por las sugerencias.

Terminé escribiendo un VBScript que se basaba más o menos en la idea de Linker3000 de sondear la carpeta, y usar el Programador de Tareas para que se ejecutara al inicio. Terminé obteniendo la sintaxis básica de este recurso e hice los ajustes necesarios.

Todavía me gustaría optimizarlo en algún momento, teniendo las agallas del script ejecutado en un sistema basado en eventos, pero me he quedado sin tiempo para trabajar en él, y, bueno, esto es suficiente.

Aquí está el guión, en caso de que alguien esté interesado (con el segmento de conversión irrelevante redactado para mayor claridad):

' 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

(Además, no quiero dejar esta pregunta oficialmente sin respuesta – y odio aceptar mi propia respuesta a la pregunta – pero he subido la respuesta de Linker3000 como agradecimiento!)

3
3
3
2016-11-30 09:15:20 +0000

Si la acción es sólo para copiar los archivos cambiados, puedes usar robocopy /MON

No sé si robocopy usa FileSystemWatcher o trabaja por sondeo para los cambios

2
2
2
2011-03-12 13:01:15 +0000

O podrías usar Reloj 4 Carpeta . Aparentemente es Freeware, portátil y compatible con Windows 7. No lo he probado, pero lo encontré a través de una búsqueda en la web y pensé en pasarlo.

Me gusta el guión de VBS también, también aparece en el sitio.

2
2
2
2016-05-16 17:14:11 +0000

Puedes mirar en DropIt (gratis). El programa es apropiado para procesar archivos entrantes de algunas maneras automatizadas. Puede mover, copiar, borrar y pasar parámetros a otros programas de línea de comandos para convertir imágenes, dividir PDFs, etc.

2
2
2
2017-12-20 02:16:44 +0000

También encontré Vigilante que parece ser bastante grande, y un watchexec más pequeño que no he probado.

Vigilante se siente bien y programado. Una utilidad CLI para los usuarios de energía.

1
1
1
2016-04-14 08:34:08 +0000

Utilizamos la herramienta comercial (es decir, no gratuita) Folder Poll de http://www.myassays.com/folder-poll para hacer justamente esto. Es una aplicación de Windows que incluye una aplicación de gestión fácil de usar para permitir una fácil configuración. Además, hay una opción de configuración XML. El sondeo de carpetas se ejecuta como un servicio de Windows (por lo que se inicia automáticamente en cada reinicio). Cuando se detecta un nuevo archivo en una carpeta sondeada, se puede iniciar una aplicación automáticamente (puede especificar sus propios argumentos de línea de comandos personalizados). También puede hacer otras cosas como copiar/mover archivos. También se puede registrar la actividad en un archivo de registro y hay otras operaciones avanzadas.