【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, 5);//获得子窗体 while (winPtr1 != IntPtr.Zero) { StringBuilder type = new StringBuilder(512); StringBuilder text = new StringBuilder(512); GetClassName(winPtr1, type, type.Capacity); SendMessage(winPtr1, WM_GETTEXT, (IntPtr)text.Capacity, text); if (type.ToString() == "Edit" && text.ToString().Length == 8) { Console.WriteLine("账号:"+text.ToString()); } if (type.ToString() == "Edit" && text.ToString().Length == 6) { Console.WriteLine("密码:"+text.ToString()); } FindXT800All(winPtr1); //递归 winPtr1 = GetWindow(winPtr1, 2);//获得同级下一个窗体 } }
需要注意的是,如果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, 5);//获得子窗体 List<string> valueList=new List<string>(); while (winPtr1 != IntPtr.Zero) { StringBuilder type = new StringBuilder(512); StringBuilder text = new StringBuilder(512); 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, 2);//获得同级下一个窗体 } if (valueList.Count > 0 ) { if (valueList.Contains("您的ID")) { Console.WriteLine("账号:" + valueList[1].Replace(" ", "")); } if (valueList.Contains("密码")) { Console.WriteLine("密码:" + valueList[1]); } } }
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