前言
数个月前我整理一套 windows 平台的效率工具,文章链接
里面总结的软件操作,再经过了我几个月的运用,已经熟练地应用到我的日常工作当中了。
只是软件的数量有点多,手动安装起来还是挺麻烦的。
这个月初就开始筹备实现这些软件的自动化安装了,花了不少时间,也踩了一些坑。
github 仓库地址
踩坑前奏
最初的时候,我打算是用 bat 批处理来实现软件的自动化安装。
因为经过我简单的网上搜索,我了解到,很多软件的安装包都有提供静默安装的选项,那么这些流程完全可以通过一个简单的 bat 批处理脚本实现自动化安装。
但是,我发现有些软件并没有那么好弄,比如 PotPlayer 是需要解压再进行安装的,因此没有提供静默安装的功能。
QtTabbar 1038 版本可以静默安装,但是升级包 1040 版本无法静默安装。
考虑到上述的诸多情况,我必须要实现 自动化 操作点击才可以。
于是乎,我打算利用 Python 来实现自动化流程。
一开始没有想到 autohotkey 这个自动化编程工具,因为一直想着 python 的 subprocess 可以调用命令行,通过 tkinter 开发界面。
考虑到python 自动化操作 windows ,可以用的库也有不少。
比较知名的库是 pywinauto 和 pyautogui
pyautogui 是跨平台的自动化包,但是大部分通过截图识别来定位鼠标位置实现自动化,因此运行效率比较低。
具体可以参考 Stack Overflow 里面 pywinatuo 作者提供的回复 链接
pywinatuo 的优点是调用了 windows 的 API 获取窗口的信息,在这些信息基础上实现窗体匹配。
因此后面我就采用了 pywinatuo 来实现我的自动化安装流程。
pywinatuo 开发
于是我开始踩坑 pywinauto 实现界面的自动化触发。
开发的过程感受到诸多和 ahk 相同的地方。
我首先从 QTTabBar 安装入手,QTTabBar 的启动比较坑,完成安装之后,还需要点到下拉菜单来启动。
通过敲击 alt 可以让 win10 显示出快捷键,通过快捷键的方式可以实现自动化的操作。
1 |
|
通过看文档和网上查资料,总算是知道怎么在 pywinauto 里面获取到打开的 explorer 窗口。
CabinetWClass
这个参数是通过 pywinauto 的 print_control_identifiers 获取 - 文档
print_control_identifiers 会打印出当前窗口下所有的组件信息。
从中我发现 explorer 这个大窗口类就是 CabinetWClass
通过这个方法可以直接获取到 explorer 打开的窗口。
然后通过 send_keys 发送键盘的命令实现自动化操作。
好不容易实现 python 的自动化, Tkinter 界面也尝试弄了些 checkbox 来进行软件安装的选择。
后续测试了一下 pyinstaller 打包程序,这一打包就直接原地炸了。
pywinauto 打包出来的 exe 居然有 200+ M
这个大小和 numpy 打包有得一拼了(:з」∠)
所以我果断放弃了这个方案了,网上稍微又查了查,才发现原来还有 autohotkey 的方案。
autohotkey 开发界面
以前用 tkinter 开发界面的时候,就有提过 tkinter 打包的界面稍微还是有点大,如果用 ahk 可以压缩得更小。Python - Tkinter Windows 磁盘映射工具
关于 ahk 的认识,我基本上是从 capslock+ 魔改的时候认识的 github仓库
所以我并没有真正开发过 ahk 界面。
不过我这一次的界面开发需求其实很简单,只需要开发几个 checkbox 界面即可。
不过开发 ahk 界面果然还是非常不习惯。
这个东西和 tkinter 一样也有同样的问题,没有 Qt 的 Layout 的概念。
所以界面的长宽位置大小都是固定的,窗口也无法进行缩放。
不过,考虑到 ahk 超级小的大小,还是太香了,委曲求全可还行。
注 : 也有可能我对 ahk 还了解不深(:з」∠)
后面在 ahk 中文网 上了解到了 中文最强 IDE , 河许人出品。 链接
这个工具可以实现类似 QtDesigner 的界面拖拽的效果。
不过界面修改起来很麻烦,人工修改代码需要断开界面的链接 ε=(´ο`*)))
用起来有诸多不爽的地方。
界面开发其实倒还好说,官方文档也非常全面,和 mel 文档有得一拼,每个命令都有个小案例,学习起来非常便利。
最大的难点就是如何获取 checkbox 的状态。
在组件的长宽后面加上 v 开发的变量名,可以绑定一个状态变量进去。
后续触发Gui, Submit ,NoHide
之后就可以让这些变量获取到 checkbox 的状态。
1 | Gui Add, GroupBox, x10 y6 w120 h205, 效率软件 |
+Checked
添加标记可以让 checkbox 保持勾选的状态。
autohotkey 自动化安装流程
大部分的安装的可以静默安装来完成。
需要特殊处理有的 QtTabbar 和 PotPlayer , 还有 msi 同时安装会导致冲突。
QtTabbar 自动化安装
这个工具安装可谓是花费了我好多时间。
因为插件安装完成之后并没有进行启动,而这个插件启动的方式又比较隐秘,参考上面的截图。
启动需要点击下拉菜单实现。
如果不将启动流程自动化,反而会比较让人困惑。
后面又在网上找到了中文语言的配置文件,于是又想实现自动加载语言配置的功能。
通过查 QtTabbar 的官方网站提供的文档
我发现 QtTabbar 的架构还是非常灵活的。
最重要的是还支持 Scripting ,可以通过 windows 的 Active Scripting 来调用 QtTabbar 的 API。 文档
支持 windows 平台的 VBScript 和 JScript。
官方提供的的案例都是 JScript 写的。
我查了一下微软官方关于 JScript 的描述,直接惊呆了。
JScript 是根据 ECAMscript 3.0 的标准做的脚本语言(其实就是 JavaScript , 只不过版本过于过时)
感觉回到10多年前的 IE 时代,那个时候 JScript 可以通过调用 ActiveXObject 实现对 windows API 的调用。
至于如何通过 JScript 来操作 QtTabbar ,官网提供了很详细的文档 API文档
还包括一些简单的调用案例
可以通过脚本来制作一些 QtTabbar 的命令按钮,实现文件操作的自动化。
通过这个脚本操作可以实现很多细微操作,因为命令行调用 explorer 只能开启一个新的窗口,如果要新建一个 Tab 还是得用脚本实现。
JScript 的执行可以调用 windows 自带的cscript
来执行 百度百科
1 | C:\Users\timmyliang>where cscript |
cscript
是 System32 目录下的一个 exe ,可以用来执行 JScript 和 VBScript
我还是比较喜欢使用 JScript , js 毕竟也写过一段时间了。
只可惜基于 ES3 标准,很多 ES6 的写法都不支持。
原本打算通过脚本后台来实现 QtTabbar 的自启动的。
为此还专门用 procmon 来监听查看 QtTabbar 的文件输入输出流。
尽管发现了 QtTabbar 进行了很多 注册表的 写入写出 操作。
但是单纯修改注册表并不能实现 QtTabbar 多标签的自启动。
后来还是看了 QtTabbar 的官方文档,找到了 ShowToolbar 的命令可以实现这个效果。
我在自己的电脑上测试得很完美。
然而当我走安装流程的时候,发现脚本并不起作用。
ShowToolbar
命令需要有 Tab 窗口开启才可以实现调用。
但是如果还没有开启多标签页面的话,无法获取到打开的标签的实例,根本就无法调用这个方法。
最后无奈,只能还是采用之前 python 自动化弄过的 快捷键操作实现 开启。
自动化开启有可能因为用户操作等问题,导致开启不成功。这个自动操作的体验也不是太友好,但是没有更好的方法了。
后来找到汉化语言 xml 配置,于是想将 汉化 添加上。
只要通过快捷键开启 QTTabBar 之后,就可以愉快地使用 JScript API 了。
于是我又查了文档,并没有直接加载 语言设置 的功能,但是可以通过加载 全局设置 功能间接加载 语言设置。
全局设置可以通过 QTTabBar 的设置界面进行导出。
API 文档 通过 Import 命令可以加载 xml 配置。
但是 xml 的配置只能是个绝对路径。
因此我需要实现 JScript 的文件拷贝和读写功能,实现对路径的替换。
1 | var shell = new ActiveXObject("wscript.shell"); |
通过 FileSystemObject 无法处理 utf-8 的文件。
因此需要用 ADODB.Stream 来读写 utf-8 的 xml 配置
这里通过 JScript 直接将文件拷贝到 APPDATA 的目录下,这个目录一般不需要管理员权限。
安装流程见上图,缺点就是敲快捷键的时候,如果遇到用户操作或者过于卡顿会导致启动失败。
PotPlayer 安装
QTTabbar 是最为艰难的了,后续这些问题都不算太大的问题。
PotPlayer 的安装包没有提供静默安装的方案,安装包需要经过解压才可以执行安装。
这个基本上利用 AHK 的按键自动化点击即可。
其中的难点就是要实现窗口等待。
1 | ; PotPlayer 安装操作 |
点击安装按钮有时候会卡主,所以弄了个循环10次进行点击。
后续进入安装流程,定期点击 关闭 按钮直到窗口关闭为止。
Snipaste 安装
Snipaste 只提供了压缩包的便捷安装版本。
因此自动安装需要用过 ahk 实现压缩包的解压
还好 ahk官方论坛上有提供解决方案。
也是通过调用 windows 的 API 实现的。
1 | Unz(sZip, sUnz) |
解压之后再执行 Snipaste.exe 启动
msi 处理
msi安装如果同时启动 /passive 安装会跳过只保留一个。
因此加入死循环来检测是否 msiexec.exe 在运行
1 | install_Quicker(){ |
总结
这次尝试了 ahk 的图形化编程,打包之后的程序大小只有 1M+ ,真的非常小巧。
自动化安装流程有一定的安装失败几率,这个可能因电脑而异。