特定のアクションを実行するために、特定のファイルの作成と削除を監視するプログラムがあります。.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は多少信頼性が低い可能性があることを認識していますが、この場合、問題を一貫して再現できます。ある時点で、時間が許せば、このファイル監視コンポーネントをもう少し安定したものに置き換えます。