如何使用C#断开本地Windows用户连接,解决多账号登录异常?
解决Windows多账户登录连接冲突问题
错误原因
你遇到的Multiple connections to a server or shared resource by the same user...错误,是Windows的安全限制机制:不允许同一客户端使用不同用户名重复连接到同一服务器/共享资源(本地机器也属于这个范畴)。之前验证test账户时建立的网络连接未释放,导致验证test1时触发冲突。
解决方案
方法1:强制断开所有网络连接
通过Windows内置的net use命令断开所有现存网络连接,C#中可通过调用进程执行该命令:
using System.Diagnostics; public void DisconnectAllNetworkConnections() { var psi = new ProcessStartInfo("net", "use * /delete /y") { CreateNoWindow = true, UseShellExecute = false, RedirectStandardOutput = true }; using (var process = Process.Start(psi)) { process.WaitForExit(); // 如需日志可读取process.StandardOutput,此处省略 } }
调用该方法后,再重新尝试验证test1账户即可。
方法2:精准断开指定用户的会话
如果需要仅断开目标用户(如test)的本地会话,可使用Windows Terminal Services API:
首先添加API声明与工具类:
using System; using System.Runtime.InteropServices; public static class WtsSessionHelper { [DllImport("wtsapi32.dll")] private static extern bool WTSEnumerateSessions(IntPtr hServer, int Reserved, int Version, out IntPtr ppSessionInfo, out int pCount); [DllImport("wtsapi32.dll")] private static extern void WTSFreeMemory(IntPtr pMemory); [DllImport("wtsapi32.dll")] private static extern bool WTSDisconnectSession(IntPtr hServer, int SessionId, bool bWait); [DllImport("wtsapi32.dll")] private static extern bool WTSQuerySessionInformation(IntPtr hServer, int SessionId, WTS_INFO_CLASS WTSInfoClass, out IntPtr ppBuffer, out int pBytesReturned); public enum WTS_INFO_CLASS { WTSUserName = 5 } public static void DisconnectUserSession(string targetUserName) { IntPtr localServerHandle = IntPtr.Zero; IntPtr sessionInfoPtr = IntPtr.Zero; int sessionCount = 0; try { if (WTSEnumerateSessions(localServerHandle, 0, 1, out sessionInfoPtr, out sessionCount)) { int sessionStructSize = Marshal.SizeOf(typeof(WTS_SESSION_INFO)); IntPtr currentSessionPtr = sessionInfoPtr; for (int i = 0; i < sessionCount; i++) { var sessionInfo = (WTS_SESSION_INFO)Marshal.PtrToStructure(currentSessionPtr, typeof(WTS_SESSION_INFO)); if (sessionInfo.State == WTS_CONNECTSTATE_CLASS.WTSActive) { IntPtr userNameBuffer = IntPtr.Zero; int bytesReturned = 0; if (WTSQuerySessionInformation(localServerHandle, sessionInfo.SessionId, WTS_INFO_CLASS.WTSUserName, out userNameBuffer, out bytesReturned)) { string sessionUserName = Marshal.PtrToStringAnsi(userNameBuffer); if (string.Equals(sessionUserName, targetUserName, StringComparison.OrdinalIgnoreCase)) { WTSDisconnectSession(localServerHandle, sessionInfo.SessionId, true); } WTSFreeMemory(userNameBuffer); } } currentSessionPtr += sessionStructSize; } } } finally { if (sessionInfoPtr != IntPtr.Zero) { WTSFreeMemory(sessionInfoPtr); } } } private struct WTS_SESSION_INFO { public int SessionId; public IntPtr WinStationNamePtr; public WTS_CONNECTSTATE_CLASS State; } private enum WTS_CONNECTSTATE_CLASS { WTSActive, WTSConnected, WTSConnectQuery, WTSShadow, WTSDisconnected, WTSIdle, WTSListen, WTSReset, WTSDown, WTSInit } }
使用时直接调用:
WtsSessionHelper.DisconnectUserSession("test");
优化验证逻辑避免连接残留
如果你的需求仅为验证账户合法性,而非实际建立会话,可尝试使用带ContextOptions参数的ValidateCredentials重载,减少持久连接的产生:
result = principalContext.ValidateCredentials( userName, password, ContextOptions.Negotiate | ContextOptions.SecureSocketLayer );
注意事项
- 以上操作均需要管理员权限才能执行,否则会出现权限不足的错误。
内容的提问来源于stack exchange,提问作者azhar rahi
相关产品推荐
相关产品推荐

