VB.NET开发Windows服务时FileSystemWatcher不触发事件问题求助
VB.NET Windows服务FileSystemWatcher不触发事件问题排查
问题现象
- 基于
FileSystemWatcher开发的Windows文件夹监听服务可正常安装、启动,向监听目标路径C:\temp\新增、删除文件时,无任何监听事件触发 - 系统事件日志仅存在服务启动时写入的
started watcher记录,无其他事件日志、无报错信息 - 已尝试将拆分的监听逻辑整合为单类、精简冗余代码,参考大量VB/C#的
FileSystemWatcher实现案例仍未定位根因,初步怀疑与服务权限配置相关
原始问题代码
Imports System.IO Public Class TestFileWatcher Dim WithEvents watcher As System.IO.FileSystemWatcher Dim myLog As System.Diagnostics.EventLog Dim folderName As String Dim fileTypes As String Protected Overrides Sub OnStart(ByVal args() As String) myLog = New System.Diagnostics.EventLog() If Not EventLog.SourceExists("My Test Log") Then EventLog.CreateEventSource("My Test Log", "Application") End If myLog.Source = "My Test Log" folderName = "C:\temp\" fileTypes = "*.*" Try watcher = New System.IO.FileSystemWatcher() DefineWatcher() watcher.EnableRaisingEvents = True myLog.WriteEntry("started watcher") Catch ErrorHandler(e) System.Environment.Exit(-1) End Try End Sub Protected Overrides Sub OnStop() StopWatcher() End Sub Public Sub StopWatcher() watcher.Dispose() End Sub Public Sub RecordOnEventLog(ByVal str As String) myLog.WriteEntry(str) End Sub Protected Sub ErrorHandler(ByVal e As ApplicationException) Dim err As String err = "ERROR" + vbCrLf err += "Message: " + e.Message + vbCrLf err += "Source: " + e.Source + vbCrLf err += "Method: " + e.TargetSite.Name + vbCrLf err += "Stack Trace: " + e.StackTrace + vbCrLf err += "Error String: " + e.ToString + vbCrLf err += "Application shut down at " & My.Computer.Clock.GmtTime.ToString myLog.WriteEntry(err) End Sub Public Sub DefineWatcher() watcher.BeginInit() watcher.Path = folderName watcher.Filter = fileTypes watcher.IncludeSubdirectories = False watcher.NotifyFilter = System.IO.NotifyFilters.FileName watcher.NotifyFilter = watcher.NotifyFilter Or System.IO.NotifyFilters.Attributes watcher.NotifyFilter = watcher.NotifyFilter Or System.IO.NotifyFilters.CreationTime watcher.NotifyFilter = watcher.NotifyFilter Or System.IO.NotifyFilters.Security AddHandler watcher.Created, AddressOf OnCreated AddHandler watcher.Deleted, AddressOf OnDeleted watcher.EndInit() End Sub Public Sub OnCreated(src As Object, e As FileSystemEventArgs) RecordOnEventLog("New file added to temp folder, path: " + e.FullPath) End Sub Public Sub OnDeleted(src As Object, e As FileSystemEventArgs) RecordOnEventLog("Item deleted") End Sub End Class
根因与修复方案
代码存在多个会直接导致事件不触发、错误被掩盖的问题,按优先级修复即可:
- 修复异常捕获逻辑缺陷
原代码OnStart中的Catch块未声明异常对象,却直接调用ErrorHandler(e),只要初始化阶段抛出任何异常,Catch块自身就会触发未处理错误,完全无法写入错误日志,直接掩盖真实报错。需修改为显式捕获异常实例:Catch ex As Exception ErrorHandler(New ApplicationException("Watcher initialization failed", ex)) System.Environment.Exit(-1) End Try - 删除运行时无效的初始化方法调用
BeginInit()、EndInit()是供Visual Studio设计器承载组件时使用的方法,运行时手动调用会干扰FileSystemWatcher的正常初始化状态,直接删除这两行即可。 - 补充
FileSystemWatcher的Error事件绑定
权限不足、内部缓冲区溢出、监听路径失效等运行时错误,只会通过Error事件抛出通知,原代码未绑定该事件,所有运行时错误都会被静默忽略。添加事件绑定与处理逻辑:' 在DefineWatcher中添加事件绑定 AddHandler watcher.Error, AddressOf OnWatcherError ' 新增错误处理方法 Public Sub OnWatcherError(src As Object, e As ErrorEventArgs) Dim ex = e.GetException() RecordOnEventLog($"Watcher error: {ex.Message}, stacktrace: {ex.StackTrace}") End Sub - 验证服务账户的目录权限
打开服务管理器,找到对应服务打开「属性-登录」页,确认服务运行身份:- 若使用Local System账户,默认拥有本地磁盘绝大多数路径访问权限,手动检查C:\temp目录的访问控制列表,无特殊拒绝规则即可
- 若使用Local Service或自定义用户账户运行,必须手动给该账户授予C:\temp目录的读取、列出文件夹内容、更改权限
- 调整监听配置避免事件丢失
原代码仅配置了文件名、属性、创建时间、安全相关的通知过滤,可按需补充LastWrite、DirectoryName过滤项;默认8KB内部缓冲区在高频文件操作下极易溢出,建议设置为64KB(不要超过64KB,避免占用过多非分页内存):watcher.InternalBufferSize = 65536 ' 64KB watcher.NotifyFilter = NotifyFilters.FileName Or NotifyFilters.Attributes Or NotifyFilters.CreationTime Or NotifyFilters.Security Or NotifyFilters.LastWrite Or NotifyFilters.DirectoryName
内容的提问来源于stack exchange,提问作者Amy
相关产品推荐
相关产品推荐

