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

WTSQueryUserToken存在活动会话时仍返回空hImpersonationToken问题求助

WTSQueryUserToken 返回0的排查与解决
  • 确认服务运行权限
    你的Windows服务必须以LocalSystem账户运行,且需拥有SE_TCB_NAME(替换进程级令牌)权限。可通过本地安全策略(secpol.msc)配置:

    1. 打开「本地策略」→「用户权限分配」
    2. 找到「替换进程级令牌」,添加LocalSystem账户
  • 验证活动会话ID的有效性
    不要仅依赖WTSGetActiveConsoleSessionId(),尤其是远程桌面场景下该API可能失效。建议枚举所有会话筛选活跃状态的ID:

    List<int> activeSessions = new List<int>();
    IntPtr pSessionInfo = IntPtr.Zero;
    int sessionCount = 0;
    
    if (WTSEnumerateSessions(IntPtr.Zero, 0, 1, ref pSessionInfo, ref sessionCount) != 0)
    {
        int sessionStructSize = Marshal.SizeOf(typeof(WTS_SESSION_INFO));
        IntPtr currentPtr = pSessionInfo;
    
        for (int i = 0; i < sessionCount; i++)
        {
            WTS_SESSION_INFO sessionInfo = (WTS_SESSION_INFO)Marshal.PtrToStructure(currentPtr, typeof(WTS_SESSION_INFO));
            if (sessionInfo.State == WTS_CONNECTSTATE_CLASS.WTSActive)
            {
                activeSessions.Add(sessionInfo.SessionId);
            }
            currentPtr = IntPtr.Add(currentPtr, sessionStructSize);
        }
        WTSFreeMemory(pSessionInfo);
    }
    
    // 取第一个有效活跃会话ID
    if (activeSessions.Count > 0)
    {
        activeSessionId = activeSessions[0];
    }
    
  • 获取具体错误码定位问题
    调用WTSQueryUserToken返回0时,立即调用Marshal.GetLastWin32Error()获取Win32错误码,常见错误及对应原因:

    • 0x5(ERROR_ACCESS_DENIED):权限不足,检查服务账户权限配置
    • 0x80070520(ERROR_NO_SUCH_LOGON_SESSION):传入的会话ID无效或该会话无登录用户
  • 检查DuplicateTokenEx参数正确性
    确保SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation和TOKEN_TYPE.TokenPrimary参数正确传递,且phUserToken初始值为IntPtr.Zero。

内容的提问来源于stack exchange,提问作者Humzamanzur

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 23:46:05