C#でFileSystemWatcherを使用して複数のフォルダ(サブディレクトリではない)を監視する最良の方法は何ですか?
7 に答える
FSWは複数のフォルダーの監視をサポートしていないと思うので、監視するフォルダーごとに1つインスタンス化するだけです。ただし、イベントハンドラーを同じメソッドにポイントすることはできますが、最終的には希望どおりに機能するはずです。
最も簡単な方法は、 FileSystemWatcherオブジェクトの複数のインスタンスを作成することです。
http://www.c-sharpcorner.com/UploadFile/mokhtarb2005/FSWatcherMB12052005063103AM/FSWatcherMB.aspx
2つのフォルダ間のイベントを正しく処理することを確認する必要があります。
ファイルのコピーや移動などの一般的な発生はイベントに直接対応していませんが、これらの発生によりイベントが発生します。ファイルをコピーすると、システムはファイルのコピー先のディレクトリでCreatedイベントを発生させますが、元のディレクトリではイベントを発生させません。ファイルを移動すると、サーバーは2つのイベントを発生させます。ソースディレクトリでのDeletedイベントと、それに続くターゲットディレクトリでのCreatedイベントです。
たとえば、FileSystemWatcherの2つのインスタンスを作成します。FileSystemWatcher1は「C:\ MyDocuments」を監視するように設定されており、FileSystemWatcher2は「C:\YourDocuments」を監視するように設定されています。これで、「MyDocuments」から「YourDocuments」にファイルをコピーすると、CreatedイベントがFileSystemWatcher2によって発生しますが、FileSystemWatcher1に対してはイベントは発生しません。コピーとは異なり、ファイルまたはディレクトリを移動すると2つのイベントが発生します。前の例から、ファイルを「マイドキュメント」から「あなたのドキュメント」に移動した場合、CreatedイベントはFileSystemWatcher2によって発生し、DeletedイベントはFileSystemWatcherによって発生します。
FileSystemEventArgsへのリンク
デフォルトでは、FileSystemWatcher は単一の親ディレクトリの監視のみをサポートしています。複数の兄弟ディレクトリを監視するには、FileSystemWatcher の複数のインスタンスを作成する必要があります。
ただし、FileSystemWatcher のサブディレクトリを含める機能を利用して、この動作をごまかすことができます。監視しているディレクトリのサブディレクトリとして、NTFS ジャンクション ポイント (別名シンボリック リンク) を作成できます。Sysinternals で有名な Mark Russinovich は、シンボリック リンクの作成と管理を簡素化するJunctionというユーティリティを持っています。
ローカル マシン上のディレクトリへのシンボリック リンクしか作成できないことに注意してください。
これは古い質問ですが、良い答えがどこにも見つからなかったので、答えることにしました。
では、目的は FileSystemWatcher を使用して複数のフォルダー (サブディレクトリではなく) を監視することでしたか? これが私の提案です:
using System;
using System.IO;
using System.Security.Permissions;
using System.Collections.Generic;
namespace MultiWatcher
// ConsoleApplication, which monitors TXT-files in multiple folders.
// Inspired by:
// http://msdn.microsoft.com/en-us/library/system.io.filesystemeventargs(v=vs.100).aspx
{
public class Watchers
{
public static void Main()
{
Run();
}
[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
public static void Run()
{
string[] args = System.Environment.GetCommandLineArgs();
// If a directory is not specified, exit program.
if (args.Length < 2)
{
// Display the proper way to call the program.
Console.WriteLine("Usage: Watcher.exe PATH [...] [PATH]";
return;
}
List<string> list = new List<string>();
for (int i = 1; i < args.Length; i++)
{
list.Add(args[i]);
}
foreach (string my_path in list)
{
Watch(my_path);
}
// Wait for the user to quit the program.
Console.WriteLine("Press \'q\' to quit the sample.");
while (Console.Read() != 'q') ;
}
private static void Watch(string watch_folder)
{
// Create a new FileSystemWatcher and set its properties.
FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Path = watch_folder;
/* Watch for changes in LastAccess and LastWrite times, and
the renaming of files or directories. */
watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
| NotifyFilters.FileName | NotifyFilters.DirectoryName;
// Only watch text files.
watcher.Filter = "*.txt";
// 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;
}
// 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);
}
}
}
ディレクトリごとに1つずつ、FileSystemWatcherの複数のインスタンスを単純に使用できますか?
オブジェクトの複数のインスタンスをインスタンス化する必要がありFileSystemWatcher
ます。ただし、イベントを同じメソッドにバインドし、送信者オブジェクトを使用してFileSystemWatcher
、イベントをトリガーしたものを判別できます。
var fsw1 = new FileSystemWatcher();
var fsw2 = new FileSystemWatcher();
FileSystemEventHandler fsw_changed = delegate(object sender, FileSystemEventArgs e)
{
Console.WriteLine("{0} - {1}", (sender as FileSystemWatcher).Path, e.ChangeType);
};
fsw1.Changed += fsw_changed;
fsw2.Changed += fsw_changed;