我有一个程序可以监视特定文件的创建和删除以执行特定操作。我们使用 .NET FileSystemWatcher 来监视围绕这些特定文件的活动。该程序在 .NET 3.5 上作为 Windows 服务运行,并使用 C# 编码。我们遇到了一个问题,即使用 Windows DEL 命令或 ERASE 命令删除正在监视的文件不会触发任何 FileSystemWatcher 事件(更改、删除、创建、错误、重命名)。这似乎只是我的 Windows 2003 和 Windows 2008 机器上的问题,而不是我的 Windows 7 机器上的问题。它在 Windows 7 上运行良好。为此我在 Google 上进行了广泛搜索,并查看了几篇 StackOverflow 帖子,但都没有运气。我玩过 FileSystemWatcher 的不同配置 - 增加了缓冲区,尝试了 NotifyFilter 枚举的各种组合,打开 IncludeSubdirectories,增加和减少涉及修改文件和运行程序的用户的权限 - 所有这些都没有成功。我在我的事件处理程序的顶部放置了一个断点,它永远不会碰到 DEL 或 ERASE。它确实适用于创建和重命名 (REN)。作为一种解决方法,我们只是在删除文件之前重命名文件。但我想知道是否有解决方案。我可以通过某种方式对其进行编码,或者是否可以在 Windows 框上更改某些配置,这将导致服务获取 DEL 或 ERASE。这是我的文件观察器的代码(为简洁起见,删除了评论):我在我的事件处理程序的顶部放置了一个断点,它永远不会碰到 DEL 或 ERASE。它确实适用于创建和重命名 (REN)。作为一种解决方法,我们只是在删除文件之前重命名文件。但我想知道是否有解决方案。我可以通过某种方式对其进行编码,或者是否可以在 Windows 框上更改某些配置,这将导致服务获取 DEL 或 ERASE。这是我的文件观察器的代码(为简洁起见,删除了评论):我在我的事件处理程序的顶部放置了一个断点,它永远不会碰到 DEL 或 ERASE。它确实适用于创建和重命名 (REN)。作为一种解决方法,我们只是在删除文件之前重命名文件。但我想知道是否有解决方案。我可以通过某种方式对其进行编码,或者是否可以在 Windows 框上更改某些配置,这将导致服务获取 DEL 或 ERASE。这是我的文件观察器的代码(为简洁起见,删除了评论):或者是否有一些我可以在 Windows 框中更改的配置会导致服务获取 DEL 或 ERASE。这是我的文件观察器的代码(为简洁起见,删除了评论):或者是否有一些我可以在 Windows 框中更改的配置会导致服务获取 DEL 或 ERASE。这是我的文件观察器的代码(为简洁起见,删除了评论):
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 可能有些不可靠,但在这种情况下,我可以始终如一地重现该问题。在某个时候,如果时间允许,我们将用更稳定的东西替换这个文件监视组件。