如何监视Windows目录以进行更改?

时间:2009-04-17 15:32:11

标签: windows directory monitoring

当在Windows系统上的目录中进行更改时,我需要立即通知程序更改。

发生变化时是否有某种方式执行程序?

我不是C / C ++ / .NET程序员,所以如果我可以设置一些东西,以便更改可以触发批处理文件,那么这将是理想的。

8 个答案:

答案 0 :(得分:25)

使用下面的FileSystemWatcher创建一个WatcherCreated事件()。

我用它来创建一个Windows服务,它监视一个Network文件夹,然后在新文件到达时通过电子邮件发送指定的组。

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

答案 1 :(得分:8)

FileSystemWatcher是正确的答案,除了它曾经是FileSystemWatcher一次仅用于“少数”更改。那是因为操作系统缓冲区。实际上,每当复制许多小文件时,保存更改的文件的文件名的缓冲区就会溢出。这个缓冲区实际上并不是跟踪最近更改的正确方法,因为当缓冲区已满时,操作系统必须停止写入以防止超出。

Microsoft提供其他工具(编辑:如更改日记)以真正捕获所有更改。这基本上是备份系统使用的设施,并且在记录的事件上很复杂。而且记录也很差。

一个简单的测试是生成大量的小文件,看看它们是否都是由FileSystemWatcher报告的。如果您遇到问题,我建议回避整个问题,并按时间间隔扫描文件系统中的更改。

答案 2 :(得分:6)

如果您想要非程序化的内容,请尝试GiPo@FileUtilities ...但在这种情况下问题不属于此处!

答案 3 :(得分:3)

答案 4 :(得分:3)

我在搜索监控文件系统活动的方法时来到了这个页面。我拿了Refracted Paladin的帖子和他分享的FileSystemWatcher并编写了一个快速而肮脏的C#实现:

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

要使用此功能,请下载Visual Studio(Express会这样做)。创建一个名为Folderwatch的新C#控制台应用程序,并将我的代码复制并粘贴到Program.cs中。

作为替代方案,您可以使用Sys Internals Process Monitor:Process Monitor它可以监控文件系统以及更多内容。

答案 5 :(得分:2)

Windows没有附带的实用程序或程序来执行此操作。需要一些编程。

如另一个答案所述,.NET的FileSystemWatcher是最简单的方法。

原生API ReadDirectoryChangesW使用起来比较困难(需要了解完成端口)。

答案 6 :(得分:1)

这个问题帮助我理解了File Watcher系统。我实现了ReadDirectoryChangesW来监视目录及其所有子目录,并获取有关这些目录中的更改的信息。

我已经在同一篇文章上写了一篇博文,我想分享一下,这样可以帮助那些在这里找到同样问题的人。

Win32 File Watcher Api to monitor directory changes

答案 7 :(得分:1)

在 github 上搜索了几个小时,按照此处的指示寻找 FileSystemWatcher 代码后,我发现以下页面有几个但相似的替代方案,可以解决 FileSystemWatcher 的缺点(也在某些的答案):

https://github.com/theXappy/FileSystemWatcherAlts

一个比较表,说明哪种替代方案更适合每种情况,底部的一般经验法则解释了在哪种情况下使用哪种替代方案:

https://github.com/theXappy/FileSystemWatcherAlts/blob/master/AltComparison.md

它很容易实现或修改。如果您的项目已经在使用 FileSytemWatcher,您可以简单地进行更改:

FileSystemWatcher sysMonitor = new FileSystemWatcher(@"C:\");

对于以下任何一个:

IFileSystemWatcher sysMonitor = new FileSystemRefreshableWatcher(@"C:\");
IFileSystemWatcher sysMonitor = new FileSystemAutoRefreshingWatcher(@"C:\");
IFileSystemWatcher sysMonitor = new FileSystemPoller(pollingInterval: 500,path: @"C:\");
IFileSystemWatcher sysMonitor = new FileSystemOverseer(pollingInterval: 500, path: @"C:\");