1

特定のアクションを実行するために、特定のファイルの作成と削除を監視するプログラムがあります。.NET FileSystemWatcherを使用して、これらの特定のファイル周辺のアクティビティを監視します。このプログラムは、.NET 3.5上でWindowsサービスとして実行され、C#でコード化されています。Windows DELコマンドまたはERASEコマンドを使用して監視対象のファイルを削除しても、FileSystemWatcherイベント(変更、削除、作成、エラー、名前変更)が発生しないという問題が発生しました。これは、Windows2003およびWindows2008ボックスでのみ問題になっているようですが、Windows7ボックスでは問題ではありません。これはWindows7で正常に動作します。私はこれについて広範囲にグーグルで検索し、運が悪かったいくつかのStackOverflowの投稿を確認しました。FileSystemWatcherのさまざまな構成で遊んだことがあります-バッファーを増やし、NotifyFilter列挙型のさまざまな組み合わせを試しました、IncludeSubdirectoriesをオンにし、ファイルの変更とプログラムの実行に関与するユーザーのアクセス許可を増減しましたが、すべて成功しませんでした。イベントハンドラーの上部にブレークポイントを設定しましたが、DELまたはERASEにヒットすることはありません。作成と名前変更(REN)で機能します。回避策として、ファイルを削除する前にファイルの名前を変更しているだけです。しかし、私はこれに対する解決策があるかどうか知りたいです。何らかの方法でコーディングできるか、Windowsボックスで変更できる構成があり、サービスがDELまたはERASEを取得するようになります。これが私のファイルウォッチャーのコードです(簡潔にするためにコメントは削除されています):イベントハンドラーの上部にブレークポイントを設定しましたが、DELまたはERASEにヒットすることはありません。作成と名前変更(REN)で機能します。回避策として、ファイルを削除する前にファイルの名前を変更しているだけです。しかし、私はこれに対する解決策があるかどうか知りたいです。何らかの方法でコーディングできるか、Windowsボックスで変更できる構成があり、サービスがDELまたはERASEを取得するようになります。これが私のファイルウォッチャーのコードです(簡潔にするためにコメントは削除されています):イベントハンドラーの上部にブレークポイントを設定しましたが、DELまたはERASEにヒットすることはありません。作成と名前変更(REN)で機能します。回避策として、ファイルを削除する前にファイルの名前を変更しているだけです。しかし、私はこれに対する解決策があるかどうか知りたいです。何らかの方法でコーディングできるか、Windowsボックスで変更できる構成があり、サービスがDELまたはERASEを取得するようになります。これが私のファイルウォッチャーのコードです(簡潔にするためにコメントは削除されています):または、サービスがDELまたはERASEを取得する原因となるWindowsボックスで変更できる構成がありますか。これが私のファイルウォッチャーのコードです(簡潔にするためにコメントは削除されています):または、サービスがDELまたはERASEを取得する原因となるWindowsボックスで変更できる構成がありますか。これが私のファイルウォッチャーのコードです(簡潔にするためにコメントは削除されています):

using System;
using System.IO;
using System.Runtime.Serialization;

namespace GatewayEDI.ClaimRouter.FileManagement
{
    public delegate void FileChangedEventHandler(object sender, FileChangedEventArgs e);

    public enum Status
    {
        Added,
        Changed,
        Deleted,
        Unknown
    }

    public class FolderWatcher : IDisposable
    {
        protected FileSystemWatcher Watcher;

        public Status FileStatus
        {
            get;
            set;
        }

        public event FileChangedEventHandler FileChanged;

        public virtual void OnHasFileChanged(FileChangedEventArgs e)
        {
            FileChangedEventHandler fileChanged = FileChanged;
            if (fileChanged != null)
            {
                fileChanged(this, e);
            }
        }

        public FolderWatcher(string path, string file)
        {
            FileStatus = Status.Unknown;
            if (!string.IsNullOrEmpty(path) && !string.IsNullOrEmpty(file))
                CreateFileSystemWatcher(path, file);
        }

        private void CreateFileSystemWatcher(string path, string file)
        {
            Watcher = new FileSystemWatcher();

            try
            {
                if (path.LastIndexOf("\\", StringComparison.CurrentCulture) < path.Length - 1)
                    path += "\\";

                Watcher.Path = path;
                Watcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.DirectoryName | NotifyFilters.LastAccess | NotifyFilters.LastWrite;
                Watcher.Filter = file;

                Watcher.Created += WatcherChanged;
                Watcher.Changed += WatcherChanged;
                Watcher.Renamed += WatcherChanged;
                Watcher.Deleted += WatcherChanged;
                Watcher.Error += WatcherError;
                Watcher.EnableRaisingEvents = true;
            }
            catch (Exception ex)
            {
                FileStatus = Status.Unknown;
                throw new FolderWatcherException("Unexpected exception searching file.  Path = " + Watcher.Path + ".  Error = " + ex.Message, ex);
            }
        }

        void WatcherError(object sender, ErrorEventArgs e)
        {
            FileStatus = Status.Unknown;
            SendFileChangedEvent();
        }

        void WatcherChanged(object sender, FileSystemEventArgs e)
        {
            switch (e.ChangeType)
            {
                case WatcherChangeTypes.Created:
                    FileStatus = Status.Added;
                    break;
                case WatcherChangeTypes.Changed:
                    FileStatus = Status.Changed;
                    break;
                case WatcherChangeTypes.Renamed:
                    FileStatus = e.Name.Equals(Watcher.Filter) ? Status.Added : Status.Deleted;
                    break;
                case WatcherChangeTypes.Deleted:
                    FileStatus = Status.Deleted;
                    break;
                default:
                    FileStatus = Status.Unknown;
                    break;
            }

            SendFileChangedEvent();
        }

        protected void SendFileChangedEvent()
        {
            string fileName = Watcher == null ? string.Empty : Watcher.Filter;
            FileChangedEventArgs args = new FileChangedEventArgs
            {
                FileStatus = FileStatus,
                FileName = fileName
            };
            OnHasFileChanged(args);
        }

        public void DeleteFile()
        {
            FileInfo fi = new FileInfo(Watcher.Path + Watcher.Filter);
            try
            {
                fi.Delete();
            }
            catch (Exception ex)
            {
                throw new FolderWatcherException("Error deleting file.  Path = " + Watcher.Path + ", File = " + Watcher.Filter + ".  Error = " + ex.Message, ex);
            }
        }

        private bool _alreadyDisposed;

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool isDisposing)
        {
            if (_alreadyDisposed)
                return;
            if (isDisposing)
            {
                if (Watcher != null)
                    Watcher.Dispose();
            }
            _alreadyDisposed = true;
        }

        ~FolderWatcher()
        {
            Dispose(false);
        }
    }

    [Serializable]
    public class FolderWatcherException : Exception
    {
        public FolderWatcherException()
        {
        }

        public FolderWatcherException(string message) : base(message)
        {
        }

        public FolderWatcherException(string message, Exception inner) : base(message, inner)
        {
        }

        protected FolderWatcherException(SerializationInfo info, StreamingContext context) : base(info, context)
        {
        }
    }
}

ファイルを変更するために使用するWindowsコマンドは次のとおりです。

Create:  echo creating main flag > Main.flg
Delete:  DEL Main.flg
Rename:  REN Main.flg Main1.flg

FileSystemWatcherは多少信頼性が低い可能性があることを認識していますが、この場合、問題を一貫して再現できます。ある時点で、時間が許せば、このファイル監視コンポーネントをもう少し安定したものに置き換えます。

4

1 に答える 1

0

自分の Windows Server 2008 R2 ボックスでこの問題を再現できるかどうかを確認するために、小さなプログラムを作成しました。これが私のコードです:

using System;
using System.IO;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            FileSystemWatcher fsw = new FileSystemWatcher();
            fsw.Path = @"D:\test";
            fsw.Deleted += new FileSystemEventHandler(ReportChange); 
            fsw.Created += new FileSystemEventHandler(ReportChange);
            fsw.EnableRaisingEvents = true;

            Console.In.ReadLine();
        }

        private static void ReportChange(object source, FileSystemEventArgs e)
        {
            // Specify what is done when a file is created or deleted.
            Console.WriteLine("File: " + e.FullPath + " " + e.ChangeType);
        }
    }
}

上記のコードは、監視していたディレクトリからのファイルの削除を正常に報告しました。

コードをよく見ると、どのファイルを監視するかを FSW に正確に伝えているように見えます。私には、これはタイミングの問題のように見えます。貼り付けたコードに基づいて、FSW の作成がファイルの削除プロセスにどのように適合するかわかりません。監視したいファイルが削除される前に、FSW が作成、初期化、有効化されていることを確認してください。私の疑いでは、ファイルが最初に削除され、次に実際にはもう存在しない特定のファイルを監視するために FSW が作成されています。

于 2012-12-13T21:16:46.850 に答える