远程桌面控制和自动 Skype






4.98/5 (60投票s)
Skype 自动化允许用户通过内置的屏幕共享功能控制另一个用户的桌面。
- 下载演示 - 192 KB
- 下载源代码 - 593 KB
(`Skype4COM.dll` 应从源代码的 `..\Common` 文件夹中获取。)
引言
大多数个人电脑都具有**动态** IP 地址和防火墙保护。因此,它们之间即时的数据交换(特别是屏幕共享)需要一个具有**永久** IP 地址的中介,该中介可供双方发出出站请求,并能够在双方之间传输数据。云计算解决方案提供了这样的中介,例如 Microsoft Azure AppFabric Service Bus。其他选项也可用。Skype 提供了一个现成的基础设施,不仅可以进行数据交换,还可以免费传输远程机器的屏幕图像。然而,目前这是**被动**屏幕共享;即,一个 Skype 用户可以看到另一个 Skype 用户的屏幕,但无法控制远程机器。
本文介绍了一种自动化 Skype 的方法,以实现**主动**屏幕共享,允许一个 Skype 用户使用 Skype 内置的屏幕共享功能控制另一个 Skype 用户的机器。
背景
Skype 本身并没有提供太多自动化选项。Skype 网站 [1] 上宣布了一些程序 API,但尚未可用(至少对于普通用户而言)。我找到的唯一 Skype API 是 `Skype4COM.dll` 进程内 COM 对象。`Skype4COM` 允许进行 Skype 用户帐户管理、通话等操作。但大多数 Skype 设置未涉及,屏幕共享也完全不在其范围之内。显然,应将其他自动化技术与 `Skype4COM` 结合使用以实现主动屏幕共享。
本文中的 Skype 自动化包括以下协同工作的技术
- 使用 Skype 公司提供的 `Skype4COM.dll`,
- 通过 Windows 消息从进程外部控制 Skype 窗口,
- 激活 Skype 应用程序菜单命令(要使用此技术,Skype 设置“工具”->“选项...”->“常规设置”->“窗口视觉样式”应设置为“经典 Windows”),
- 模拟用户操作,如鼠标点击和移动,以及向相应的 Windows 控件写入文本,最后
- 将外部代码注入正在运行的 Skype 进程。
概念
该项目的主要思想是利用 Skype 通信基础设施进行双方之间的所有数据交换。目标机器(屏幕暴露的机器)的屏幕图像作为视频传输到远程机器。在远程机器上,包含图像的 Skype 窗口被注入到 Skype 进程中的代码子类化。子类化窗口过程感知鼠标移动和点击、文本输入等,并为目标机器生成命令以实际在那里实现这些操作。命令构成包含动作名称(“函数”)和相关参数(“参数”)的短文本消息。例如,执行鼠标左键点击的命令提供点击点的坐标作为参数。命令通过 Skype 文本消息在机器之间传输。
它是如何工作的?
在我们的场景中,为了获得技术支持,一名 Skype **用户**将其机器的屏幕共享给另一名 Skype 用户,该用户在下文中称为**顾问**。相应的应用程序在顾问和用户机器上运行,即 `AdviserSkypeDriver.exe` 和 `UserSkypeDriver.exe`(这些应用程序与内核驱动程序无关)。SkypeDrivers 共享几个组件,如 `WindowFinderNET` 用于通过窗口类查找窗口,`HumanActionSimulation` 用于重现鼠标点击和移动以及文本输入,以及 `SkypeAutoHelper` 用于通过 `HumanActionSimulation` 和 `Skype4COM` 实际控制 Skype。
两个 SkypeDrivers 都有一个“启动/附加到 Skype”按钮。通过按下此按钮,顾问和用户要么启动驱动程序,要么将驱动程序附加到已经运行的 Skype 实例,并将 Skype 设置为“视图”->“紧凑视图”模式(这样做是为了简化后续操作)。如果驱动程序是第一次附加到 Skype,则会出现一个警告对话框请求权限。驱动程序会自动按下“允许访问”按钮。成功附加操作后,驱动程序会启用其“关闭 Skype”按钮。
注意:目前,上述操作部分基于超时;因此它们需要一些时间(甚至可能会失败,哎),所以请耐心等待。
现在,顾问和用户应将对方 Skype 句柄的字符串键入其各自 SkypeDriver 表单中唯一的文本框。此时,用户停止其活动,顾问接管用户机器的控制权。
当顾问键入可用用户的 Skype 句柄时,“呼叫”按钮会启用 `AdviserSkypeDriver` 主表单。顾问按下“呼叫”按钮,开始呼叫用户。在用户端,`UserSkypeDriver` 接受顾问的呼叫(在其 `Skype4COM` 组件 API 的帮助下),并通过在 Skype 主窗口(图 2)中的“共享”和“显示整个屏幕”自绘按钮上自动执行两次连续的鼠标左键单击来启动屏幕共享。
为确保准确命中,目标窗口首先被设为最顶层窗口,设置为预定义的固定大小,并移动到屏幕的左上角。这确保了目标窗口中的每个对象都与屏幕原始左上角具有固定偏移量,并且可以通过鼠标轻松点击。
当用户的 Skype 设置为屏幕共享模式时,顾问通过按下“弹出”将用户屏幕图像放置到一个单独的窗口中,并通过按下“实际大小”将其图像调整为其实际大小(图 3;将来,上述两个操作可以通过模拟鼠标点击来自动化,类似于在用户端所做的操作)。
最后,顾问在 `AdviserSkypeDriver` 应用程序的主表单上按下“自动化”按钮,将 `SkypePlugin.dll` 注入到 Skype 进程中(注入技术在 [2, 3] 中详细讨论)。
`SkypePlugin` 子类化了包含远程屏幕图像的外部(帧,`WNDCLASS_TLiveConversationWindow`)和内部(视图)窗口。新的子类化窗口过程处理与鼠标点击和移动、按键、字符插入等相关的 Windows 消息。外部窗口的子类化窗口过程还创建了一个包装在 COM 可调用包装器 (CCW) 中的 `SkypeHandlerNET` 组件的托管对象。`SkypeHandlerNET.dll` 是一个托管程序集,其对象应包装在 CCW 中,以便非托管 `SkypePlugin` 将其视为 COM。`SkypeHandlerNET` 组件负责与 `AdviserSkypeDriver` 应用程序通信。WCF 使用快速命名管道 (net.pipe) 绑定进行此通信。WCF 服务由 `AdviserSkypeDriver` 应用程序托管,而 `SkypeHandlerNET` 充当客户端(注入代码中托管对象的使用在 [4] 中讨论)。
带有屏幕图像的自动化 Skype 窗口被放大,其标题扩展了 `(Automated)` 后缀。现在,顾问在自动化窗口中的操作,例如鼠标左键和右键点击(双击尚未实现)以及文本输入,将通过 Skype 文本消息传输到用户机器,并由 `UserSkypeDriver` 实际执行。要将鼠标切换为控制自动化窗口本身(例如,在窗口内移动图像,或按下其自绘按钮),鼠标操作应与顾问机器键盘上按下的 Shift 按钮结合使用。
**注意**:图像上某一点的坐标仅在图像的一个角与自动化窗口的相应角(实际上,这些是左上角或左下角)重合时,才正确转换为目标机器上的屏幕坐标。
用于传输命令的文本消息具有以下格式
command(param0, param1, ..., paramN-1)integer
其中 `command` 表示要在远程端执行的操作名称,`(param0, param1, ..., paramN-1)` 构成放置在括号内并用逗号分隔的操作参数,`integer`(介于 1 到 100 之间)用于区分连续消息(有时,`Skype4COM` 组件错误地在收到相同消息时生成多个通知)。例如,消息 `lck(759,498)49` 指示接收方在屏幕坐标 (759,498) 处执行鼠标左键单击;消息 `mv(752,170,777,70)33` 导致接收方模拟以下操作序列:“在 (752,170) 处按下鼠标左键 - 将鼠标移动到 (777,70) - 释放鼠标左键”;消息 `s(a, b, c)71` 导致在接收方当前光标位置键入括号内的字符串(在本例中为“a, b, c”,逗号将被视为字符串的一部分而不是分隔符)。
运行演示
本文的演示包含两个文件夹:`Adviser` 和 `User`。**`Skype4COM.dll` 应从源项目的 `..\Common` 文件夹中获取,并在任何其他操作之前添加到 `Adviser` 和 `User` 文件夹中**(此 DLL 已从演示中删除以减小上传大小)。在顾问机器上,`Adviser` 文件夹的内容应放置在与 `Skype.exe` 相同的文件夹中(在 Skype 的默认安装中,这是 `[磁盘盘符]:\Program Files\Skype\Phone` 文件夹),并在安装后运行 `COMRegistration.cmd` 命令(批处理)文件一次。之后,`AdviserSkypeDrive.exe` 即可工作。在用户机器上,`User` 文件夹的内容应放置在一个单独的文件夹中,`UserSkypeDrive.exe` 无需额外准备即可工作(`UserSkypeDrive.exe` 本身将 `Skype4COM.dll` 注册为进程内 COM)。演示面向 32 位平台。
讨论和进一步开发
本文和代码只是通过 Skype 屏幕共享控制远程机器的概念验证。除了修复错误(当然有很多 :)),代码还可以通过多种方式增强。下面列出了一些方面
- 可以添加额外功能(例如,鼠标双击)。
- 可以改进文本传输的性能。目前,顾问以文本消息形式向用户发送的命令是由注入到 Skype 中的代码生成的。然后,这些命令通过 WCF 传输到 `AdviserSkypeDriver`,并从那里通过激活 `Skype4COM` API 发送回 Skype 进程。可能有一种方法可以直接从注入的代码向用户发送文本消息。
- 调查 Skype 流媒体基础设施及其用于传输专有数据的用途可能会带来一些成果。
- 可以生成不同类型的日志和报告,并将其发送到第三个 Skype 帐户(与顾问和用户不同),例如,用于商业用途的计费目的。
- 可以添加结合简单命令的复杂命令(例如,多次连续的鼠标点击)以实现特定目标(例如,打开特定日志)。
本文提出了一种通过自动化 Skype 控制远程机器的方法。Skype 的标准免费流媒体基础设施用于屏幕共享,Skype 即时文本消息用作命令传输的媒介。本文介绍了用于用户和顾问的专用应用程序,它们使用各种自动化技术。这种方法可能对客户支持有用,将主动屏幕共享与用户和顾问之间的音频对话相结合。
谢谢
我要感谢 telemagic 对本文主题的非常有益的讨论和建议。
参考文献
- 介绍 SkypeKit Beta 版计划.
- Jeffrey Richter,Christophe Nasarre。《Windows via C/C++》。第五版。Microsoft Press,2008。
- Igor Ladnik。《自动化 Windows 应用程序》。CodeProject。
- Igor Ladnik。《使用配备 WCF 的注入组件自动化 Windows 应用程序》。CodeProject。