【Win32 API】远程工具调用
前言
有时候,影城报障需要远程过去重现和处理,如果电脑没有安装远程工具的话,还需要营业员下载和安装,然后将账号密码发送过来,这样一来一回操作繁琐也浪费时间,所以我们可以设想一下这种场景,售票员点击在pos点击远程协助按钮,运维童鞋就在后台看到相应的远程账号和密码,瞬间远程过去。如果要实现这个功能的话,我们需要pos能够获取远程工具的账号和密码,回传到服务端。那么,我们就市面上比较常用的远程工具试试看吧。
XT800
协通800是国内的一款远程工具,有官方的SDK可以集成到我们的系统中,不过是要收费的。我们现在要做的是不收费的,测试的版本是4.3.8版本,界面如下

使用spy++工具,得知大部分元素如 "本机号码","授权码"等都是统一封装在名为XTMainRemoteWnd的类上,这些封装的元素是获取不到的,只有少部分元素是有句柄的,如下图

我们需要获取元素正好有句柄的,是可以读取,但是没其他元素可以辅助定位,那么我们只能通过长度来判断了,代码如下
static void FindXT800()
{
IntPtr windowHandler = FindWindow(null, "XT800 个人版"); //获得句柄
FindXT800All(windowHandler);
}
static void FindXT800All(IntPtr intPtr)
{
IntPtr winPtr1 = GetWindow(intPtr, );//获得子窗体
while (winPtr1 != IntPtr.Zero)
{
StringBuilder type = new StringBuilder();
StringBuilder text = new StringBuilder();
GetClassName(winPtr1, type, type.Capacity); SendMessage(winPtr1, WM_GETTEXT, (IntPtr)text.Capacity, text); if (type.ToString() == "Edit" && text.ToString().Length == )
{
Console.WriteLine("账号:"+text.ToString());
}
if (type.ToString() == "Edit" && text.ToString().Length == )
{
Console.WriteLine("密码:"+text.ToString());
}
FindXT800All(winPtr1); //递归
winPtr1 = GetWindow(winPtr1, );//获得同级下一个窗体
}
}
需要注意的是,如果XT800隐藏到系统右下角的栏里就获取不到句柄的。
TeamViewer
TeamViewer是国外的一款软件,也是收费的。不过使用体验上,感觉比XT800好一点,例如支持双屏远程,这就能够很方便地操作拥有客屏的远程机。测试版本是13.2,界面如下:

使用spy++得知这个界面的元素基本都是有句柄,所以我们可以根据标题辅助定位到账号和密码,代码如下
static void FindTeamViewer()
{
IntPtr windowHandler = FindWindow(null, "TeamViewer"); //获得句柄
FindTeamViewAll(windowHandler);
}
static void FindTeamViewAll(IntPtr intPtr)
{
IntPtr winPtr1 = GetWindow(intPtr, );//获得子窗体
List<string> valueList=new List<string>();
while (winPtr1 != IntPtr.Zero)
{
StringBuilder type = new StringBuilder();
StringBuilder text = new StringBuilder();
GetClassName(winPtr1, type, type.Capacity); SendMessage(winPtr1, WM_GETTEXT, (IntPtr)text.Capacity, text); if (type.ToString() == "Static" && text.ToString()=="您的ID")//您的ID
{
valueList.Add(text.ToString());
}
if (type.ToString() == "Edit")
{
valueList.Add(text.ToString());
}
if (type.ToString() == "Static" && text.ToString() == "密码")//密码
{
valueList.Add(text.ToString());
}
if (type.ToString() == "Edit")
{
valueList.Add(text.ToString());
} FindTeamViewAll(winPtr1); //递归
winPtr1 = GetWindow(winPtr1, );//获得同级下一个窗体
}
if (valueList.Count > )
{
if (valueList.Contains("您的ID"))
{
Console.WriteLine("账号:" + valueList[].Replace(" ", ""));
}
if (valueList.Contains("密码"))
{
Console.WriteLine("密码:" + valueList[]);
}
}
}
AnyDesk
AnyDesk听说是原TeamViewer团队开发,质量还是有保证的,更关键的是它提供脚本获取账号密码,不用麻烦地获取句柄。测试版本是4.2.2,界面如下

使用spy++工具得知界面元素是有句柄的,不过我们现在是使用它的api获取账号和设置密码,方法是通过执行放在程序目录下的bat文件获取,具体代码如下:
static void Main(string[] args)
{
ExecBatFile("GetUserId.bat");
ExecBatFile("SetPassword.bat");
Console.ReadLine();
}
static void ExecBatFile(string file)
{
ProcessStartInfo pro = new ProcessStartInfo("cmd.exe");
pro.UseShellExecute = false;
pro.CreateNoWindow = true;
pro.RedirectStandardInput = true;
pro.RedirectStandardOutput = true;
pro.RedirectStandardError = true;
pro.FileName = file;
pro.WorkingDirectory = Environment.CurrentDirectory;
Process proc = Process.Start(pro);
proc.Start(); StreamReader sOut = proc.StandardOutput;
proc.WaitForExit();
proc.Close();
string results = sOut.ReadToEnd().Trim(); //回显内容
Console.WriteLine(results);
sOut.Close();
}
小结
上文比较了三种远程工具的账号密码获取方式,目前来看,anydesk的获取方式最靠谱,毕竟是官方的API,其他两款走的都是旁门左道。另外anydesk不用安装,只有一个2m的exe程序,非常方便集成在我们的产品中。个人还是比较推荐anydesk的。
参考文档
https://blog.csdn.net/zcheva/article/details/76063017
https://blog.csdn.net/FaaronZheng/article/details/46897033
【Win32 API】远程工具调用的更多相关文章
- MSIL 教程(二):数组、分支、循环、使用不安全代码和如何调用Win32 API(转)
转自:http://www.cnblogs.com/Yahong111/archive/2007/08/16/857574.html 续上文[翻译]MSIL 教程(一) ,本文继续讲解数组.分支.循环 ...
- C#调用Win32 api学习总结
从.NET平台调用Win32 API Win32 API可以直接控制Microsoft Windows的核心,因为API(Application Programming Interface)本来就是微 ...
- Python调用win32 API绘制正弦波
Python调用win32 API新建窗口与直接创建窗口的流程相同 流程:注册窗口→创建窗口→显示窗口→更新窗口→消息循环 代码: # -*- coding: utf-8 -*- import win ...
- C#调用Win32 api时的内存操作
一般情况下,C#与Win 32 Api的互操作都表现的很一致:值类型传递结构体,一维.二维指针传递IntPtr.在Win32 分配内存时,可以通过IntPtr以类似移动指针的方式读取内存.通过IntP ...
- Java APi 之 RMI远程方法调用
一.什么是RPC RPC全称是remote procedure call,即远程过程调用.它是一种协议,用于从远程计算机上请求服务. 例如有两台服务器A和B,A上的应用想要调用B上应用的方法,但是他们 ...
- nodejs 调用win32 api
video 教程文件 win32 api >node -v v12.16.1 >npm install -g node-gyp >npm i @saleae/ffi >node ...
- Detours简介 (拦截x86机器上的任意的win32 API函数)
Detours 当然是用detours,微软明显高腾讯一筹,同上,至今没失败过.写这种HOOK一定要再写个测试程序,不要直接HOOK你的目的程序,例如QQ,因为这样不方面更灵活的测试.说明一下:Det ...
- MSComm控件与Win32 API操作串口有何区别?
MSComm控件与Win32 API操作串口有何区别? [问题点数:50分,结帖人shell_shell] 收藏帖子 回复 我是一个小兵,在战场上拼命! 结帖率 83.33% 我以前用MSCo ...
- SpringBoot关于系统之间的远程互相调用
1.SpringBoot关于系统之间的远程互相调用 可以采用RestTemplate方式发起Rest Http调用,提供有get.post等方式. 1.1远程工具类 此处使用Post方式,参考下面封装 ...
随机推荐
- Day2_数字类型_字符串类型_列表类型
数字类型: 作用:年纪,等级,薪资,身份证号等: 10进制转为2进制,利用bin来执行. 10进制转为8进制,利用oct来执行. 10进制转为16进制,利用hex来执行. #整型age=10 prin ...
- qt对plot柱状图颜色设置
当使用qwtplotbarchart来使用柱状图时.可以通过下面代码来设置柱状图的颜色 QwtPlotBarChart *barChart = new QwtPlotBarChart(" ...
- 响应式前端框架Bootstrap系列(11)分页
分页功能已经封装成一个独立的js文件,也是用bs完成的,名称为bootstrap-paginator.js. 使用前先导入文件 : <script src="../libs/boots ...
- 从零开始学MySQL(三)
经过上两节的洗礼,我们能够连接上服务器,并成功地进入与mysql交互的会话中了.那么现在就可以发起SQL语句,让服务器来执行它了!这听起来很酷吧?接下来,我们开始学习MySQL的相关知识. 本文概览: ...
- AIX中设备管理
1.AIX系统中的设备概述 逻辑设备文件 #ls -l /dev 空设备文件 #/dev/null 设备的状态:undefined.defined.available.stopp ...
- 浅谈MySQL存储引擎选择 InnoDB还是MyISAM
如果是一些小型的应用或项目,那么MyISAM 也许会更适合.当然,在大型的环境下使用MyISAM 也会有很大成功的时候,但却不总是这样的.如果你正在计划使用一个超大数据量的项目,那么你应该直接使用In ...
- ZROI 19.08.03 分治与离线
经典问题,给一张图,支持加边/删边/询问两点连通性. 离线统计边权(删除时间),lct维护最大生成树即可. 也可以按时间分治,维护一个可回退并查集即可. 主定理 很好用,但是记不住. 有一种简明的替代 ...
- Python 分页和shell命令行模式
前言 除了手动添加你的文章后外,你还可以用命令行来添加,python 自带了一种命令行 就是 shell 快速添加博文:Shell命令行模式 在你的目录下:mysite python manage.p ...
- #python#return和print的一些理解
https://www.jianshu.com/p/18a6c0c76438 代码 (1) ++++++++++++++++++++++++++++++++++ x = 1y = 2def add ( ...
- chalk插件 使终端输出的字带颜色
1.使终端输出红色字体: const chalk = require('chalk'); console.log(chalk.red('this is red!') 这时运行终端,打印的this is ...