【问题标题】:How can I monitor a Windows directory for changes?如何监视 Windows 目录的更改?
【发布时间】:2010-10-20 03:23:38
【问题描述】:

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

当发生变化时,有什么方法可以执行程序吗?

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

【问题讨论】:

标签: windows directory monitoring


【解决方案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:\");

【讨论】:

    【解决方案2】:

    使用如下所示的FileSystemWatcher 创建一个WatcherCreated Event()。

    我用它创建了一个 Windows 服务,它监视网络文件夹,然后在新文件到达时向指定组发送电子邮件。

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

    【讨论】:

    • 我知道您发布的声明称您不是 .NET 程序员,但拥有 Free Visual Studio Express 的副本,而我发布的代码是 %80。 Stack OverFlow 可能会给你另一个 %20。根据您要对检测到的文件执行的操作,这是一个非常简单的实施和部署解决方案。如果您有兴趣,我可以详细说明我的帖子给谁创建窗口服务。
    • 谢谢,我已经有几年没用过C#了,但如果它是完成这项工作的最佳工具,那么付出额外的努力是值得的。我将设置 Visual C# Express Edition。谢谢。
    • 自 .NET 以来就不能在 PowerShell 中使用吗?你根本不需要视觉工作室。
    • 这里值得注意的是,.net 自己的 FileSystemWatcher 并不是 100% 可靠的。当正在监视的文件夹发生大量更改(例如同时传入几百个文件)时,它可能无法做出反应。请参阅stackoverflow.com/a/13917670/1128104 以获得很好的解释
    • 我认为您缺少“Watcher.EnableRaisingEvents = true;”。此外,您对“观察者”与“观察者”的看法不一致。
    【解决方案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 它可以监控文件系统等等。

    【讨论】:

      【解决方案4】:

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

      我已经写了一篇关于相同问题的博客文章,我想分享它,以便它可以帮助那些遇到同样问题的人。

      Win32 File Watcher Api to monitor directory changes.

      【讨论】:

        【解决方案5】:

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

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

        一个简单的测试是生成大量的小文件,看看它们是否都被 FileSystemWatcher 报告。如果您有问题,我建议您回避整个问题并定期扫描文件系统以查找更改。

        【讨论】:

          【解决方案6】:

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

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

          原生 API ReadDirectoryChangesW 更难使用(需要了解完成端口)。

          【讨论】:

            【解决方案7】:

            如果您想要一些非程序化的东西,请尝试GiPo@FileUtilities ...但在这种情况下,问题不属于这里!

            【讨论】:

            • 没错,这个问题可能更适合超级用户甚至服务器故障,但这个答案确实直接回答了 OP 的问题,“发生更改时是否有某种方法可以执行程序?”。跨度>
            • GiPo@FileUtilities 现在似乎已被删除,但如果您需要非编程的东西,myassays.com/folder-poll 会做类似的事情。
            【解决方案8】:

            【讨论】:

            • 我需要 Visual Studio 吗?我可以在 VBScript 中使用它吗?
            • FileSystemWatcher 是 .Net 所以是的,这个解决方案需要 Visual Studio。
            猜你喜欢
            • 1970-01-01
            • 2010-12-13
            • 1970-01-01
            • 2011-04-28
            • 1970-01-01
            • 1970-01-01
            • 2018-12-10
            • 2014-12-08
            • 1970-01-01
            相关资源
            最近更新 更多