2009-04-17 17 views
28

Quando si effettua una modifica all'interno di una directory su un sistema Windows, ho bisogno che un programma venga immediatamente informato della modifica.Come posso monitorare una directory di Windows per le modifiche?

Esiste un modo per eseguire un programma quando si verifica un cambiamento?

Non sono un programmatore C/C++ /. NET, quindi se potessi impostare qualcosa in modo che la modifica possa attivare un file batch, sarebbe l'ideale.

+0

Si può fare con VBScript e WMI, vedere questa implementazione http://www.go-geek.com/tips-n-tricks/monitor-directory-for-new-files-with-wsh.html – Pradeep

risposta

18

Utilizzare un FileSystemWatcher come di seguito per creare un evento WatcherCreated(). L'ho usato per creare un servizio di Windows che controlla una cartella di rete e quindi invia un messaggio di posta elettronica a un gruppo specificato all'arrivo di nuovi file.

// 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

So che dichiari che non sei un programmatore .NET ma con una copia di Free Visual Studio Express e il codice che ho postato sei% 80 af il modo in cui ci sono. Stack OverFlow può probabilmente ottenere l'altro% 20. A seconda di cosa si vuole fare con il file rilevato, questa è una soluzione molto semplice da implementare e distribuire. Se sei interessato, posso elaborare il mio post su Who Window Service Creation. –

+0

Grazie, non ho usato C# in pochi anni, ma se è lo strumento migliore per il lavoro, allora vale lo sforzo extra. Installerò Visual C# Express Edition. Grazie. – Liam

+0

non è possibile utilizzare in PowerShell dal suo .NET? non hai bisogno di studio visivo. –

3

Utilizzare un FileSystemWatcher

+0

Will Ho bisogno di Visual Studio? Posso usare questo da VBScript? – Liam

+0

FileSystemWatcher è .Net quindi sì, questa soluzione richiederebbe Visual Studio. –

6

Se si desidera qualcosa di non-programmatico provare [email protected] ... ma in quel caso la questione non apparterrebbe qui!

+0

È vero, questa domanda potrebbe essere più appropriata per superuser o anche serverfault, ma questa risposta risponde direttamente alla domanda dell'OP, "Esiste un modo per eseguire un programma quando si verifica una modifica?". – Pat

+0

GiPo @ FileUtilities sembra essere stato rimosso adesso, ma http://www.myassays.com/folder-poll fa qualcosa di simile se hai bisogno di qualcosa di non programmatico. –

1

Non c'è alcuna utilità o programma viene fornito con Windows per farlo. Alcuni programmi richiesti.

Come indicato in un'altra risposta, .NET FileSystemWatcher è l'approccio più semplice.

L'API nativa ReadDirectoryChangesW è piuttosto difficile da utilizzare (richiede una conoscenza delle porte di completamento).

7

FileSystemWatcher è la risposta giusta, tranne per il fatto che FileSystemWatcher funzionava solo per "pochi" cambiamenti alla volta. Questo era a causa di un buffer del sistema operativo. In pratica ogni volta che vengono copiati molti piccoli file, il buffer che contiene i nomi dei file modificati viene sovraccaricato. Questo buffer non è davvero il modo giusto per tenere traccia delle modifiche recenti, dal momento che il sistema operativo dovrebbe smettere di scrivere quando il buffer è pieno per prevenire i sovraccarichi.

Microsoft invece fornisce altri servizi (EDIT: come i diari di cambiamento) per acquisire veramente tutte le modifiche. Quali sono essenzialmente le strutture utilizzate dai sistemi di backup e sono complesse sugli eventi registrati. E sono anche scarsamente documentati.

Un semplice test consiste nel generare un numero elevato di file di piccole dimensioni e verificare se sono stati segnalati da FileSystemWatcher. In caso di problemi, suggerisco di ignorare l'intero problema e analizzare il file system per le modifiche a intervalli di tempo.

+1

Le "altre strutture" hanno un nome con il quale si potrebbe trovare un riferimento ad esse? La scansione di un file system di grandi dimensioni può essere lenta. (Grazie!) –

+0

@Paul, ho modificato la risposta per fornire un riferimento. Per favore, non dimenticare di modificare la mia risposta se ritieni che sia utile. –

1

Questa domanda mi ha aiutato molto a capire il Sistema di osservazione file. Ho implementato ReadDirectoryChangesW per monitorare una directory e tutte le sue sottodirectory e ottenere le informazioni sul cambiamento in quelle directory.

Ho scritto un post sul blog sullo stesso, e mi piacerebbe condividerlo in modo che possa aiutare qualcuno che arriva qui per lo stesso problema.

Win32 File Watcher Api to monitor directory changes.

2

Sono entrato in questa pagina mentre cercavo un modo per monitorare l'attività del filesystem. Ho preso rifratta post di Paladin e la FileSystemWatcher che ha condiviso e ha scritto un lavoro C# implementazione rapida e-sporco:

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); 
     } 
    } 
} 

Per utilizzare questo, scaricare Visual Studio (espresso farò). Crea una nuova applicazione console C# chiamata Folderwatch e copia e incolla il mio codice nel tuo Program.cs.

In alternativa è possibile utilizzare Sys Internals Process Monitor: Process Monitor È possibile monitorare il file system e molti altri.

Problemi correlati