2012-07-24 120 views
2

我知道(和它的作品),在C#中,此属性告诉我,如果当前会话是一个RDP之一:检测远程桌面从服务在登录时连接(W7/32)

System.Windows.Forms.SystemInformation.TerminalServerSession 

现在,我有一个接收登录/注销和锁定/解锁事件的服务,如果会话启动是rdp或本地,我需要一种方法来告诉此服务。

问题:服务作为系统用户,并且上面总是属性返回false(我想是因为系统始终被视为本地连接的用户)

我试过在寄存器来搜索Volatile环境子项来检查是否存在标识RDP会话名称的子项:它在锁定/解锁处理程序中工作,但在登录处理程序中该子项尚不存在(子项在登录完成后创建)。

有关如何解决此问题的任何想法?

尽管在有限的时间内等待密钥创建工作,但我希望采用更少的“kludgy”方法来完成。

+0

这不是因为服务是从SYSTEM运行的,而仅仅是因为它是服务。所有服务在会话0中运行,根据定义它是本地的。您目前正在获取有关新登录的信息?看到这里的API函数可用:http://msdn.microsoft.com/en-us/library/windows/desktop/aa383464%28v=vs.85%29.aspx – 2012-07-24 22:47:50

+0

我在新登录信息是那些我可以从挥发性环境中读到的东西,除此之外没有别的。正如你所说的,我可以在WTS子系统上为“当前”会话执行的每个查询都表示连接是本地连接,因此我无法从中获取信息。我想我会尝试找到一种方法来枚举*所有WTS会话并从每个会话中提取信息。在我们的机器上,只有一个并发RDP会话的强制限制,所以我期望最多只能找到一个rdp数据的会话。该会话上的QuerySessionInfos应该为我提供我需要的数据...(我希望) – Axeman 2012-07-25 07:35:56

+1

如果通过SERVICE_CONTROL_SESSIONCHANGE事件向您通知登录,则WTSSESSION_NOTIFICATION结构将包含会话ID。你只需要查询那个特定的会话。 – 2012-07-25 19:31:07

回答

2

通过调用WTSQuerySessionInformation并将WTSInfoClass参数设置为WTSClientProtocolType,可以检测会话是本地会话还是远程会话。如果您希望避免P/Invokes,则可以使用Cassia librarynew TerminalServicesManager().GetLocalServer().GetSession(sessionId).ClientProtocolType

注意事项:当处理会话注销消息时,这不会帮助您,因为您不会(可靠地)获取有关会话的信息,因为它处于被销毁的过程中(但似乎相对比较容易解决)。此外,上述提及的决明子属性ClientProtocolType尚未发布,但您可以通过登录访客并使用工件链接从build server中获取树干版本。

+0

我不知道那个图书馆......非常非常有趣,谢谢!关于注销,不是问题,因为服务只需在登录时验证协议类型。 – Axeman 2012-07-26 11:48:17