.NET 7 Windows Service中后台Worker检测用户注销异常问题
.NET 7 Windows Service 监听用户注销事件解决方案
问题根源
默认的Worker服务托管在Windows Service时,未启用会话变更事件的处理权限,对应传统ServiceBase中的CanHandleSessionChangeEvent配置,导致SystemEvents.SessionSwitch事件无法触发。
解决方案
通过自定义ServiceBase实现来替代默认托管逻辑,显式启用会话变更事件处理:
1. 创建自定义ServiceBase类
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using System.ServiceProcess; public class SessionAwareServiceBase : ServiceBase { private readonly IHost _host; private readonly ILogger<Worker> _logger; public SessionAwareServiceBase(IHost host, ILogger<Worker> logger) { _host = host; _logger = logger; // 启用会话变更事件处理权限 CanHandleSessionChangeEvent = true; } protected override void OnStart(string[] args) { _host.StartAsync().Wait(); } protected override void OnStop() { _host.StopAsync().Wait(); _host.Dispose(); } // 处理系统会话变更事件 protected override void OnSessionChange(SessionChangeDescription changeDescription) { base.OnSessionChange(changeDescription); if (changeDescription.Reason == SessionChangeReason.SessionLogoff) { _logger.LogInformation("用户注销事件触发,会话ID: {SessionId}", changeDescription.SessionId); // 在此添加你的注销逻辑处理代码 } } }
2. 修改Program.cs托管逻辑
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; var host = Host.CreateDefaultBuilder(args) .ConfigureServices(services => { services.AddHostedService<Worker>(); // 注册自定义ServiceBase实例 services.AddSingleton<SessionAwareServiceBase>(); }) .Build(); // 判断运行模式:Windows Service或控制台 if (OperatingSystem.IsWindows() && args.Contains("--service")) { var service = host.Services.GetRequiredService<SessionAwareServiceBase>(); ServiceBase.Run(service); } else { await host.RunAsync(); }
3. 部署与权限说明
- 部署服务时,使用带
--service参数的命令,示例:sc create UserLogoffMonitor binPath="C:\YourServicePath\WorkerService.exe --service" - 建议使用LocalSystem账户运行服务,该账户具备监听系统会话事件的权限。
原代码问题说明
默认Worker服务的Windows托管实现未开启会话事件处理开关,SystemEvents.SessionSwitch依赖系统向服务推送事件通知,只有当CanHandleSessionChangeEvent设为true时,系统才会发送此类事件。
内容的提问来源于stack exchange,提问作者Caironite
相关产品推荐
相关产品推荐

