【发布时间】:2022-08-02 17:32:41
【问题描述】:
让我们考虑以下场景:采用具有多个用户帐户的 Windows Server 实例(2012 或更新版本)。这些帐户中的每一个都需要以自动化的方式运行目标应用程序的单个实例,这需要一个活动的 GUI 以及编排。我们无法控制此目标应用程序,因此我们需要解决它。
经过大量研究和尝试使用诸如WTS calls(甚至LsaLogonUser)之类的win32 API 以编程方式创建交互式Windows 会话(带有GUI)后,我们放弃并尝试使用rdp 或freerdp 创建这些会话。这设法创建所需的会话。
现在讨论手头的问题。由于目标应用程序的性质以及它需要编排和自主运行的事实(需要远程触发,无需用户干预),我们选择了以下架构:
- 公开 API(可用作触发器)的 Windows 服务 - 我们称其为 \"指挥中心\"。
- 一个用户级应用程序,当每个用户登录并从前面提到的服务(通过命名管道)接收命令时自动运行。让我们称之为\"代理人\“。 这个代理人然后根据从指挥中心.
为了指挥中心为了将命令正确推送到每个代理,每个代理都具有一个命名管道服务器,该服务器具有唯一的名称:agent_[username]_[sessionid]。这确保了即使特定用户有多个运行多个代理的会话,也可以单独控制每个会话。
就触发此功能而言,流程如下:
- 一个 HTTP Rest 请求被发送到指挥中心
- 指挥中心使用 freerdp(C# 和一些 C++)以编程方式为指定用户创建一个新会话
- 会话已创建,并且代理人自动启动(从计划任务)
- 一旦会话启动并运行指挥中心连接到代理人通过目标命名管道服务器(如上面的命名方案中所述)。
步骤 3 之前的所有操作都已完成并且工作正常,但是,在创建新会话(步骤 2)时,我们在确定会话 id(和其他会话数据)时遇到了问题,因此指挥中心知道它需要向其发送命令的命名管道服务器(代理)的字符串 ID。本质上,它知道为其创建会话的用户名,但它缺少会话 ID。
我们需要做的是弄清楚如何从新创建的 freerdp 会话中获取会话数据(主要是会话 id)。我们想过但没有做到的:
- 使用WTSQuerySessionInformationA API 调用查询会话信息 - 这还不够健壮,因为您不能真正可靠地监视新创建的会话并与同一用户的现有会话协调。
- 使用自定义会话名称(例如 GUID)创建新的 freerdp 会话,这将使我们能够使用上述 API 调用自信地识别和链接会话。到目前为止,使用 freerdp 创建的所有会话都有空白会话名称,因此我们无法分配自定义名称,但这可能是一个解决方案。
- 从我们用来创建会话的rdp_rdp 对象中检索客户端信息 - 到目前为止还没有运气,因为文档非常有限,而且我们还没有设法获得这些信息 - 但是这看起来像解决我们问题的最直接和最可靠的方法。
总而言之,我们需要一种在多个不同名称的代理和服务应用程序之间进行通信的方法——为此,我们需要确定每个新创建的 Windows 会话的会话 ID 或名称。有没有办法做到这一点,或者也许我们还没有想到的替代方法?
非常感谢!
标签: c# c++ session rdp freerdp