1

Windows サービスに FileSystemWatcher オブジェクトがあります。そのアプリをコンポーネントのスタブとして使用して、コンソール アプリケーションに記述しました。

私のコンポーネントは FileSystemWatcher をインスタンス化し、マップされたドライブを監視するように設定します。これは、テスト スタブ コンソール アプリと展開可能な Windows サービスの両方からうまく機能します。

また、致命的なレベルのエラーをログに記録する log4net に接続された onError イベントもあります。

public FileSystemWatcher CreateFileWatcher()
    {
        FileSystemWatcher watcher = new FileSystemWatcher();

        try
        {
            log.Info("Configuring DPIFileWatcher");
            watcher.Filter = "*.xml";
            log.Info("DPIFileWatcher Filter set to: *.xml");
            string watcherPath = ConfigurationManager.AppSettings["InoundPath"].ToString();
            watcher.Path = watcherPath;
            log.Info(String.Format("DPIFileWatcher Path set to: {0}", watcherPath)); 

            watcher.Created += new FileSystemEventHandler(DPIWatcher_FileCreated);
            watcher.Changed += new FileSystemEventHandler(DPIWatcher_FileChanged);
            watcher.Error += new ErrorEventHandler(DPIWatcher_Error);
            watcher.EnableRaisingEvents = true;

            log.Info("DPIFileWatcher Configuration Successful.");
        }
        catch(Exception e)
        {
            log.Fatal(String.Format("Failed to configure DPIFileWatcher: {0}", e.Message));
        }

        return watcher;
    }

ここに私のエラーイベントがあります:

    private void DPIWatcher_Error(object source, ErrorEventArgs e)
    {
        log.Fatal(String.Format("FileWatacher error: {0}", e.GetException().Message));
    }

ネットワーク カードを取り外してネットワーク エラーの損失をテストすると、コンソール アプリから次のログ エラーが表示されます。

FATAL   [  12] 2013-02-12 12:14:02,142 SMILLER-E6430 METHOD: DPIWatcher_Error     GenFileWatch.DPIFileWatcher- FileWatacher error: The specified network name is no longer available (C:\Development\GenFileWatch\GenFileWatch\DPIFileWatcher.cs: 447)

ただし、このログ エラーは、Windows サービス内から実行している場合には機能しません。

誰かが理由や修正方法を知っていますか?

4

1 に答える 1

0

まず、監視しようとしているディレクトリにアクセスできるアカウントでサービスを実行していますか。99%の確率で、「コンソール」アプリの実行と「サービス」の実行は、2つの異なるユーザーコンテキストで実行されます。そのユーザーコンテキストがそのディレクトリにアクセスできない場合(またはURLが別のユーザーコンテキスト内の何かを意味するだけの場合)、OnErrorが呼び出されるとは思いません。

第二に、FileSystemWatcherかなり信頼性が低いです。ほとんどの場合は機能しますが、機能しない場合もあります。基礎となるネイティブ関数``を使用します。

ReadDirectoryChangesWを最初に呼び出すと、システムは変更情報を格納するためのバッファーを割り当てます。このバッファは、閉じられるまでディレクトリハンドルに関連付けられ、そのサイズは存続期間中に変更されません。この関数の呼び出しの間に発生するディレクトリの変更はバッファに追加され、次の呼び出しで返されます。バッファがオーバーフローした場合、バッファの内容全体が破棄され、lpBytesReturnedパラメータにゼロが含まれ、ReadDirectoryChangesW関数がエラーコードERROR_NOTIFY_ENUM_DIRで失敗します。

于 2013-02-12T22:13:20.690 に答える