[英]How can I monitor a Windows directory for changes?
当在 Windows 系统上的目录中进行更改时,我需要一个程序立即收到更改通知。
当发生更改时,是否有某种方法可以执行程序?
我不是 C/C++/.NET 程序员,所以如果我可以设置一些东西以便更改可以触发批处理文件,那将是理想的。
使用如下所示的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
}
FileSystemWatcher 是正确的答案,除了它曾经是 FileSystemWatcher 一次仅适用于“少数”更改。 那是因为操作系统缓冲区。 实际上,每当复制许多小文件时,保存已更改文件的文件名的缓冲区就会溢出。 此缓冲区并不是跟踪最近更改的真正正确方法,因为操作系统必须在缓冲区已满时停止写入以防止溢出。
相反,Microsoft 提供了其他工具(编辑:如变更日志)来真正捕获所有变更。 这些本质上是备份系统使用的设施,并且在记录的事件上很复杂。 并且记录也很差。
一个简单的测试是生成大量的小文件,看看它们是否都被 FileSystemWatcher 报告了。 如果您遇到问题,我建议您回避整个问题并定期扫描文件系统以查找更改。
如果你想要一些非编程的尝试GiPo@FileUtilities ......但在这种情况下,问题不属于这里!
这个问题对我理解文件观察器系统有很大帮助。 我实现了ReadDirectoryChangesW来监视目录及其所有子目录并获取有关这些目录中更改的信息。
我已经写了一篇关于此的博客文章,我想分享它,以便它可以帮助那些遇到同样问题的人。
我在寻找监视文件系统活动的方法时来到此页面。 我拿了 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它可以监控文件系统等等。
没有 Windows 附带的实用程序或程序可以做到这一点。 需要一些编程。
正如另一个答案中所述,.NET 的FileSystemWatcher
是最简单的方法。
原生 API ReadDirectoryChangesW更难使用(需要了解完成端口)。
按照此处的指示在 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:\");
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.