2

こんにちは私は、特定のディレクトリを監視して、ディレクトリのサイズが制限に達しているかどうかを確認するWindowsサービスを作成しています。次のようにファイルシステムウォッチャーを作成しました。

            FileSystemWatcher watcher = new FileSystemWatcher();
            watcher.Path = dirPaths[i].ToString();
            watcher.NotifyFilter = NotifyFilters.Size;
            watcher.EnableRaisingEvents = true;
            watcher.Changed += new FileSystemEventHandler(OnChanged);

 private void OnChanged(object source, FileSystemEventArgs e)
    {
        try
        {
        
        string directory = new DirectoryInfo(e.FullPath).Parent.FullName;//gettting the directory path from the full path

        float dirSize = CalculateFolderSize(directory);

        float limitSize = int.Parse(_config.TargetSize);//getting the limit size 

        if (dirSize > limitSize)
        {
            eventLogCheck.WriteEntry("the following path has crossed the limit " + directory);
            //TODO: mail sending
        }
    }
    catch (Exception ex)
    {
        eventLogCheck.WriteEntry(ex.ToString());
    }

}

CalculateFolderSizeドライブ内のすべてのファイルとサブディレクトリのサイズをチェックします。

これで、.xls、.txtなどのファイルをディレクトリに追加すると正常に機能しますが、ディレクトリにフォルダを追加してもOnChangedイベントはトリガーされませんか?

有効にした場合:

watcher.IncludeSubdirectories = true;

イベントをトリガーしOnchangedますが、この場合、ディレクトリ全体ではなく、サブディレクトリのみをチェックします。

誰かがこれを機能させる方法を教えてください。監視対象のディレクトリにフォルダをコピーすると、Onchangedイベントがトリガーされ、ディレクトリの新しいサイズが計算されます。

これが役立つ場合、私のCalculateFolderSize関数は次のようになります。

//function to calculate the size of the given path
        private float CalculateFolderSize(string folder)
        {
            float folderSize = 0.0f;
            try
            {
                //Checks if the path is valid or not         
                if (!Directory.Exists(folder))
                {
                    return folderSize;
                }
                else
                {
                    try
                    {
                        foreach (string file in Directory.GetFiles(folder))
                        {
                            if (File.Exists(file))
                            {
                                FileInfo finfo = new FileInfo(file);
                                folderSize += finfo.Length;
                            }
                        }
                        foreach (string dir in Directory.GetDirectories(folder))
                        {
                            folderSize += CalculateFolderSize(dir);
                        }
                    }
                    catch (NotSupportedException ex)
                    {
                        eventLogCheck.WriteEntry(ex.ToString());
                    }
                }
            }
            catch (UnauthorizedAccessException ex)
            {
                eventLogCheck.WriteEntry(ex.ToString());
            }
            return folderSize;
        }
4

1 に答える 1

5

によって提供されたフォルダパスを使用しているFileSystemEventArgsため、変更されたフォルダになります。代わりに、監視しているディレクトリルートごとにオブジェクトを作成し、その中にルートパスを保存して、の代わりにそれを使用しますEventArgs

このオブジェクトを作成する簡単な方法は、次のようにイベントハンドラーにラムダ関数を使用することです。これにより、外部スコープからのパスが、監視しているパスごとに異なるオブジェクトに効果的にラップされます。

 FileSystemWatcher watcher = new FileSystemWatcher();
 watcher.Path = dirPaths[i].ToString();
 watcher.NotifyFilter = NotifyFilters.Size;
 watcher.EnableRaisingEvents = true;
 watcher.Changed += delegate (object source, FileSystemEventArgs e)
 {
    float dirSize = CalculateFolderSize(watcher.Path); // using the path from the outer scope

    float limitSize = int.Parse(_config.TargetSize);//getting the limit size 

    if (dirSize > limitSize)
    {
        eventLogCheck.WriteEntry("the folloing path has crossed the limit " + directory);
        //TODO: mail sending
    }
 };
于 2012-04-27T08:35:07.740 に答える