2009-04-17 9 views
28

Cuando se realiza un cambio dentro de un directorio en un sistema Windows, necesito que se notifique un programa inmediatamente del cambio.¿Cómo puedo controlar un directorio de Windows para ver los cambios?

¿Hay alguna forma de ejecutar un programa cuando se produce un cambio?

No soy un programador de C/C++ /. NET, así que si pudiera configurar algo para que el cambio pudiera desencadenar un archivo por lotes, sería ideal.

+0

Se puede hacer con VBScript y WMI, consulte esta implementación http://www.go-geek.com/tips-n-tricks/monitor-directory-for-new-files-with-wsh.html – Pradeep

Respuesta

18

Utilice un FileSystemWatcher como a continuación para crear un evento WatcherCreated(). Lo usé para crear un servicio de Windows que mira una carpeta de red y luego envía un correo electrónico a un grupo específico al recibir nuevos archivos.

// Declare a new FILESYSTEMWATCHER 
    protected FileSystemWatcher watcher; 
    string pathToFolder = @"YourDesired Path Here"; 

    // Initialize the New FILESYSTEMWATCHER 
    watcher = new FileSystemWatcher {Path = pathToFolder, IncludeSubdirectories = true, Filter = "*.*"}; 
    watcher.EnableRaisingEvents = true; 
    watcher.Created += new FileSystemEventHandler(WatcherCreated); 

    void WatcherCreated(object source , FileSystemEventArgs e) 
    { 
     //Code goes here for when a new file is detected 
    } 
+2

Sé que publica que no es un programador .NET pero con una copia de Free Visual Studio Express y el código que publiqué es% 80 en el camino. Stack OverFlow probablemente puede obtener el otro% 20. Dependiendo de lo que quiera hacer con el archivo detectado, esta es una solución muy simple de implementar e implementar. Si está interesado, puedo elaborar mi publicación para la creación de servicios de Windows. –

+0

Gracias, no he usado C# en algunos años, pero si es la mejor herramienta para el trabajo, entonces vale la pena el esfuerzo extra. Configuraré Visual C# Express Edition. Gracias. – Liam

+0

¿no se puede usar en PowerShell ya que es .NET? no necesitas ningún estudio visual. –

3

Utilice un FileSystemWatcher

+0

Will Necesito Visual Studio? ¿Puedo usar esto desde VBScript? – Liam

+0

FileSystemWatcher es .Net así que sí esta solución requeriría Visual Studio. –

6

Si quieres algo no programática tratar [email protected] ... pero en ese caso la cuestión no pertenecería aquí!

+0

Es cierto que esta pregunta podría ser más apropiada para el superusuario o incluso el servidor, pero esta respuesta responde directamente a la pregunta del OP: "¿Hay alguna forma de ejecutar un programa cuando se produce un cambio?". – Pat

+0

GiPo @ FileUtilities parece haber sido eliminado ahora, pero http://www.myassays.com/folder-poll hace algo similar si necesita algo que no sea programático. –

1

No existe una utilidad o programa que venga con Windows para hacerlo. Alguna programación requerida.

Como se señala en otra respuesta, .NET FileSystemWatcher es el enfoque más fácil.

La API nativa ReadDirectoryChangesW es bastante difícil de usar (requiere una comprensión de los puertos de terminación).

7

FileSystemWatcher es la respuesta correcta, excepto que solía ser que FileSystemWatcher solo funcionaba para unos 'pocos' cambios a la vez. Eso fue debido a un buffer del sistema operativo. En la práctica, siempre que se copian muchos archivos pequeños, se sobrepasa el búfer que contiene los nombres de archivo de los archivos. Este búfer no es realmente la manera correcta de realizar un seguimiento de los cambios recientes, ya que el sistema operativo tendría que dejar de escribir cuando el búfer está lleno para evitar excesos.

Microsoft ofrece otras funciones (EDITAR: como diarios de cambios) para capturar realmente todos los cambios. Que esencialmente son las instalaciones que usan los sistemas de respaldo, y son complejas en los eventos que se registran. Y también están mal documentados.

Una prueba simple es generar una gran cantidad de archivos pequeños y ver si todos ellos son informados por FileSystemWatcher. Si tiene un problema, le sugiero que evite todo el problema y escanee el sistema de archivos en busca de cambios en un intervalo de tiempo determinado.

+1

¿Las "otras instalaciones" tienen un nombre por el cual se puede encontrar alguna referencia a ellas? Escanear un gran sistema de archivos puede ser lento. (¡Gracias!) –

+0

@Paul, edité la respuesta para proporcionar una referencia. No olvide invitar mi respuesta si cree que es útil. –

1

Esta pregunta me ayudó mucho a comprender el sistema File Watcher. Implementé ReadDirectoryChangesW para supervisar un directorio y todos sus subdirectorios y obtener la información sobre el cambio en esos directorios.

He escrito una publicación en el blog sobre la misma, y ​​me gustaría compartirla para que pueda ayudar a alguien que aterrice aquí por el mismo problema.

Win32 File Watcher Api to monitor directory changes.

2

Vine en esta página mientras buscaba una forma de controlar la actividad del sistema de archivos. Tomé refracta el post de Paladín y el FileSystemWatcher que compartía y escribió un trabajo de C# aplicación rápida y sucia-:

using System; 
using System.IO; 

namespace Folderwatch 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 

      //Based on http://stackoverflow.com/questions/760904/how-can-i-monitor-a-windows-directory-for-changes/27512511#27512511 
      //and http://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher.aspx 

      string pathToFolder = string.Empty; 
      string filterPath = string.Empty; 
      const string USAGE = "USAGE: Folderwatch.exe PATH FILTER \n\n e.g.:\n\n Folderwatch.exe c:\\windows *.dll"; 

      try 
      { 
       pathToFolder = args[0]; 

      } 
      catch (Exception) 
      { 
       Console.WriteLine("Invalid path!"); 
       Console.WriteLine(USAGE); 
       return; 
      } 

      try 
      { 
       filterPath = args[1]; 
      } 
      catch (Exception) 
      { 
       Console.WriteLine("Invalid filter!"); 
       Console.WriteLine(USAGE); 
       return; 

      } 

      FileSystemWatcher watcher = new FileSystemWatcher(); 

      watcher.Path = pathToFolder; 
      watcher.Filter = filterPath; 

      watcher.NotifyFilter = NotifyFilters.Attributes | NotifyFilters.CreationTime | 
       NotifyFilters.DirectoryName | NotifyFilters.FileName | NotifyFilters.LastAccess | 
       NotifyFilters.LastWrite | NotifyFilters.Security | NotifyFilters.Size; 

      // Add event handlers. 
      watcher.Changed += new FileSystemEventHandler(OnChanged); 
      watcher.Created += new FileSystemEventHandler(OnChanged); 
      watcher.Deleted += new FileSystemEventHandler(OnChanged); 
      watcher.Renamed += new RenamedEventHandler(OnRenamed); 


      // Begin watching. 
      watcher.EnableRaisingEvents = true; 

      // Wait for the user to quit the program. 
      Console.WriteLine("Monitoring File System Activity on {0}.", pathToFolder); 
      Console.WriteLine("Press \'q\' to quit the sample."); 
      while (Console.Read() != 'q') ; 

     } 

     // Define the event handlers. 
     private static void OnChanged(object source, FileSystemEventArgs e) 
     { 
      // Specify what is done when a file is changed, created, or deleted. 
      Console.WriteLine("File: " + e.FullPath + " " + e.ChangeType); 
     } 

     private static void OnRenamed(object source, RenamedEventArgs e) 
     { 
      // Specify what is done when a file is renamed. 
      Console.WriteLine("File: {0} renamed to {1}", e.OldFullPath, e.FullPath); 
     } 
    } 
} 

Para usar esto, descargar Visual Studio (expresa lo hará). Cree una nueva aplicación de consola C# llamada Folderwatch y copie y pegue mi código en su Program.cs.

Como alternativa, puede utilizar el Monitor de proceso Sys Internals: Process Monitor Puede controlar el sistema de archivos y mucho más.

Cuestiones relacionadas