C#非管理员权限下如何检测当前Windows用户处于断开连接状态?
C#检测Windows用户会话断开状态实现方案
核心原理
我们只需要查询当前程序所属的用户会话的连接状态即可,不需要枚举全系统会话,因此全程不需要管理员权限,依赖Windows系统自带的WTSAPI32.dll提供的公共API即可实现。
封装Win32 API
首先定义需要用到的枚举和平台调用代码:
using System; using System.Runtime.InteropServices; using System.Diagnostics; public static class SessionStateHelper { // 定义会话连接状态枚举 private enum WTS_CONNECTSTATE_CLASS { WTSActive, WTSConnected, WTSConnectQuery, WTSShadow, WTSDisconnected, WTSIdle, WTSListen, WTSReset, WTSDown, WTSInit } // 静态字段存当前进程所属会话ID,进程不会跨会话,所以只需要获取一次 private static readonly int _currentSessionId = Process.GetCurrentProcess().SessionId; [DllImport("wtsapi32.dll", SetLastError = true)] private static extern bool WTSQuerySessionInformation( IntPtr hServer, int SessionId, int WTSInfoClass, out IntPtr ppBuffer, out int pBytesReturned); [DllImport("wtsapi32.dll")] private static extern void WTSFreeMemory(IntPtr pMemory); // 对外公开的检测方法:返回当前用户是否处于断开状态 public static bool IsCurrentUserDisconnected() { IntPtr buffer = IntPtr.Zero; try { // 传入WTS_CURRENT_SERVER_HANDLE(值为IntPtr.Zero)代表查询本地服务器 bool ret = WTSQuerySessionInformation(IntPtr.Zero, _currentSessionId, 4 /*WTSConnectState*/, out buffer, out _); if (!ret) return false; int state = Marshal.ReadInt32(buffer); return (WTS_CONNECTSTATE_CLASS)state == WTS_CONNECTSTATE_CLASS.WTSDisconnected; } finally { if (buffer != IntPtr.Zero) WTSFreeMemory(buffer); } } }
业务逻辑集成
你可以在程序中加入定时检测逻辑,当检测到用户断开时主动退出程序:
// 示例:每隔10秒检测一次 var timer = new System.Threading.Timer(_ => { if (SessionStateHelper.IsCurrentUserDisconnected()) { // 执行自定义资源清理逻辑 Environment.Exit(0); } }, null, TimeSpan.Zero, TimeSpan.FromSeconds(10));
注意事项
- 该方案兼容Windows Server 2008及以上版本、Windows 7及以上桌面版本系统
- 仅查询当前进程所属会话的状态,完全不需要管理员权限即可正常运行
- 远程桌面连接断开、切换用户等操作都会触发会话状态变为
WTSDisconnected,符合服务器部署场景的业务需求
内容的提问来源于stack exchange,提问作者Bjørn Sigurd Benestad Johansen
相关产品推荐
相关产品推荐

