背景
为了不用考虑断网、断电的问题,我直接把 QMT 放在了 windows 服务器上运行,并且开启了「自动初始化」功能,每天的 9:20 和 20:50 都会重启应用。
但是!!!偶尔会碰到需要填验证码的情况,我就很纳闷,都点了自动登录了,还加个验证码,这是什么逻辑?!?!?!
这就导致我需要时不时的就登录服务器去看一下,有的时候赶巧了,好几天策略都没跑,简直!@FRQ#@$!@#!@#……
在技术群里也反馈这个问题了,也毫无结果,得,自己写个脚本搞定吧。
正文
原理
原理其实很简单:如果出现了验证码,那么关掉窗口,重新启动一下就好了。
所以,我们只需要在启动程序 60s 后,判断是否还是停留在登录界面(也就是登录失败),是的话重启应用就可以了。这个用 Python 实现不难。
然后就是每天定时运行这个 Python 脚本就可以了,这个用 windows 自带的「计划任务」功能就可以了。
下面先给出脚本的代码,然后再写一下使用步骤,其实还是有一些小门槛的。
import time
import pywinauto as pw
EXE_NAME = "XtItClient.exe"
EXE_PATH = r'C:\iQuant\bin.x64\XtItClient.exe'
EXE_TITLE_RE = "国信iQuant策略交易平台 *" # Change if needed
LOGIN_TIME = 60 # Time to wait for the login
def login():
try:
proc_id = pw.application.process_from_module(EXE_NAME)
print('proc_id:', proc_id)
app = pw.application.Application(backend="uia").connect(process=proc_id)
app.kill()
except Exception:
pass
app = pw.Application(backend='uia').start(EXE_PATH, timeout=10)
time.sleep(5)
try:
# Wait for the login window to disappear
time.sleep(LOGIN_TIME)
login_window = app.window(title_re=EXE_TITLE_RE, control_type="Pane")
login_window.wait('visible', timeout=1)
print('Login failed, retrying...')
login()
except (pw.findwindows.ElementNotFoundError, pw.timings.TimeoutError):
print('Login successful!')
if __name__ == '__main__':
login()
注意:
LOGIN_TIME是等待几秒后检查是否登录成功,如果机器比较慢或者网络比较慢,把这个值改大点即可。代码中的
EXE_TITLE_RE是 QMT 程序启动时的 title,是个正则值。只要把鼠标 hover 到任务栏中正在运行的应用上,就能看到了。各位同学使用的券商可能不一样,修改一下就可以了。因为是正则,所以忽略后面的版本号即可。
使用步骤
1. 自动登录 QMT
首先我们先人工登录一下 QMT 程序,登录的时候勾选「记住密码」和「自动登录」,如下图:
登录后把「账号自动登录」和「策略自动运行」配置好,然后关闭「自动重启设置」里面的两个选项,取消勾选,如下图:
保证我们每次打开程序,不需要输入用户名和密码,能够自动登录程序即可。
2. 测试脚本
- 在服务器上安装 Python,把上面的代码复制生成
auto_login.py文件; - 如需要,修改脚本中的变量;
pip install pywinauto;- 运行脚本
py auto_login.py查看效果。
3. 新建计划任务
笔者之前写过一篇 《如何在 windows 服务器上开机启动程序》大概介绍了一下「计划任务」怎么用,那个时候还没有完全解决这个问题,不过可以当作入门教程来看。如何新建任务这里就不展开了,只说几个要点:
- 因为依赖
pywinauto,所以一定要有 GUI 环境才能运行,也就是说要勾选「只在用户登录时运行」才可以; - 触发时间设置为每周一到周五
- 操作这里,「程序」一定要填
python.exe的地址,不能直接写脚本地址,否则会跳出选项让你选择用什么程序运行。脚本地址写在「添加参数」里面。 - 新建成功后,记得运行测试一下,是否能成功运行脚本。
4. 用 VNC 保持服务器的 GUI 会话
做完了以上的工作,本以为完成了,结果第二天登录一看,脚本根本没有运行。后来才知道,原来关闭与服务器的连接之后,GUI 会话就关闭了。没有 GUI 环境,pywinauto 是无法正常运行的。问过 ChatGPT 之后,终于找到了解决办法。
我把它整理成了另一篇文章:《解决windows服务器「计划任务」无法运行GUI脚本的问题》,笔者用的是 TightVNC,具体的操作我就不在这里重复了,大家看这篇文章即可。
搞完了才知道,用 Windows 服务器也是分 Level 的:
- 菜鸟:云服务网页登录;
- 老手:
.rdpwindows 远程桌面; - 高手:
.vncVNC Server 应用。
总结
按照上面的步骤搞完,QMT 自动登录问题就解决了。写下来才发现,好像也挺复杂的。只是笔者有「计划任务」和「VNC」的知识储备,所以觉得不太难。现在回想起来,当时也是踩了不少坑的。不过很值得,因为笔者还有其它功能也需要依赖这些。
说远了,说回 QMT 自动登录。因为现在我的策略还很简单,所以用的服务器是最低配的「2核4G」,还算便宜,不过随着后面策略的复杂度增加,这个配置估计就不太够用了。于是笔者绞尽脑汁,终于找到了一个终极版省钱办法,我把它整理成了《省钱妙招:windows服务器开机登录GUI》一文,有兴趣的同学可以看看。