[英]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.