You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 20:55:10