问题背景:
我的毕业设计中需要在Windows平台上面跨进程操作窗口。实际上是获取浏览器上面的网页中的文本框元素,还有windows32窗体上面的编辑框。然后进行自动填值等的操作。
我能想到的一共有这么几种方法:
使用C#编写窗体应用程序,然后使用WebBrowser浏览器控件或者嵌入其他应用程序窗口。如果使用WebBrowser控件,只能强制用户使用该C#应用程序上网,影响用户体验,不切实际。如果使用嵌入其他应用程序窗口的方式,其实就转化为了跨进程获取窗口的方法了。
使用浏览器插件的方式,针对不同浏览器编写不同插件,然后让用户安装。当浏览器页面载入后,使用驻留程序(这是我毕设的核心进程)向浏览器发消息,执行浏览器插件中的JS代码操作网页DOM元素。但是缺点是需要编写很多插件,且调试起来,真正执行起来很艰难。
先使用远程线程注入到目标进程的线程空间,创建一个虚拟线程,然后执行这个虚拟线程,向拥有这个窗口的界面线程发送消息。实际上这个方法和上面的方法大同小异。只不过进程注入行为会被用户系统的安全机制检测到,类似360安全卫士这种神经质的安全软件会让用户把我们的程序查杀掉。另外需要针对各种浏览器,各种程序窗体做特定的分析处理,代价太大,而我只不过是完成一个毕设,没必要用牛刀吧。
- 使用模拟用户操作方式。先拿简单的方法说,很多脚本语言例如在Windows上面的VBS脚本执行时会启动WScript驻留进程,使用VBS的
sendKey
命令可以模拟用户的输入,甚至VBS能模拟用户鼠标的点击。还可以使用Python,JS(需要先让用户下载python)等都可以。他们的核心其实都是调用Windows系统API来完成功能,从结构上来看都是要运行一个本地即时解释器,它可以调用WindowsAPI,然后解释脚本执行操作。再说深层次一点就是先获取目标窗口的句柄,然后对该窗体的消息处理队列发送WM_SET_TEXT,WM_GET_TEXT,WM_EXIT等各种消息。 本文考虑到毕设需要具有跨平台的特性,并且最好能够兼容各种不同版本的Windows。因此使用Java语言的JNA包提供的方便的功能调用WindowsAPI。而是用JNI也可以。只不过还要编写DLL,编译再加调试,会浪费很长时间。如果不是针对特定问题,使用成熟的JNA况且会帮助你解决低层调用的各种问题,何乐而不为呢。
摘取一些JNA简介:
JNA提供Java程序轻松访问本机共享库,而不需要编写任何Java代码 - 不需要JNI或本机代码。这个功能与Windows的Platform / Invoke和Python的ctypes类似。
JNA允许您使用Java的方法调用来直接调用本机函数。调用看起来就像本机代码中的调用一样。大多数的方法调用不需要特殊的处理或配置。