web-dev-qa-db-ja.com

Windowsディレクトリの変更を監視するにはどうすればよいですか?

Windowsシステムのディレクトリ内で変更が行われた場合、その変更をすぐに通知するプログラムが必要です。

変更が発生したときにプログラムを実行する方法はありますか?

私はC/C++ /。NETプログラマーではないので、変更によってバッチファイルがトリガーされるように何かをセットアップできれば、それが理想的です。

32
Liam

以下のように 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
    }
25

FileSystemWatcherは、FileSystemWatcherが一度に「わずかな」変更に対してしか機能しなかったことを除いて、正しい答えです。これは、オペレーティングシステムのバッファが原因でした。実際には、多くの小さなファイルがコピーされるたびに、変更されたファイルのファイル名を保持するバッファーがオーバーランします。このバッファは、オーバーランを防ぐためにバッファがいっぱいになると書き込みを停止する必要があるため、実際には最近の変更を追跡する正しい方法ではありません。

代わりに、Microsoftはすべての変更を真にキャプチャするために他の機能(編集:変更ジャーナルのような)を提供します。基本的に、バックアップシステムが使用する機能であり、記録されるイベントに関して複雑なものです。また、文書化も不十分です。

簡単なテストは、多数の小さなファイルを生成し、それらがすべてFileSystemWatcherによって報告されているかどうかを確認することです。問題がある場合は、問題全体を回避し、一定の間隔でファイルシステムの変更をスキャンすることをお勧めします。

9

非プログラム的な何かを試してみたい場合は、 GiPo @ FileUtilities ...ですが、その場合、質問はここに属しません!

6
Rob Walker

FileSystemWatcher を使用します

3
SQLMenace

ファイルシステムのアクティビティを監視する方法を探しているときにこのページにアクセスしました。 Refracted Paladinの投稿と、彼が共有し、迅速で汚れのないC#実装を作成した FileSystemWatcher を取り上げました。

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 ファイルシステムを監視し、さらに多くを監視できます。

3
Eric

Windowsに付属するユーティリティやプログラムはありません。プログラミングが必要です。

別の回答で述べたように、.NETの FileSystemWatcher が最も簡単なアプローチです。

ネイティブAPI ReadDirectoryChangesW の使用はかなり困難です(完了ポートの理解が必要です)。

2
Richard

この質問は、File Watcher Systemを理解するのに大いに役立ちました。 ReadDirectoryChangesW を実装して、ディレクトリとそのすべてのサブディレクトリを監視し、それらのディレクトリの変更に関する情報を取得しました。

同じブログ記事を書いたので、同じ問題でここにたどり着く人を助けることができるように共有したいと思います。

ディレクトリの変更を監視するWin32 File Watcher API

1
Neha