python实现自动打开终端并执行代码(windows)
- 一、环境和代码
- 1. 安装pypiwin32
- 2. 代码示例
- 二、效果展示
- 三、存在问题
- 1. ImportError: DLL load failed while importing win32api: 找不到指定的模块。
- 2. 窗口打开了但是不输入命令
最近有同学需要同时打开多个terminal并在其中执行不同代码的需求,linux中可以使用xterminal,但是windows就不行,需要手动打开多个终端,但这样费时费力,因此本文就自动打开终端并执行命令,给出下面的python代码。
一、环境和代码
1. 安装pypiwin32
在虚拟环境中安装pypiwin32的包,注意需要将pywin32的版本控制在305以下,否则会有坑(见第三部分第一个), 这里使用的是225版本:
pip install pypiwin32
pip install pywin32==225
2. 代码示例
直接上代码看看,如下所示,其实基本步骤就是:
-
- 定义一下不同键盘字符对应的code
-
- 定义自己需要输入的命令字符串
-
- 打开窗口
-
- 置顶窗口
-
- 输入指令执行
import subprocess
import sys
from time import *
import win32api
import win32con
import win32gui# 定义键盘的字符对应的16进制code
key_map = {"0": 0x30, "1": 0x31, "2": 0x32, "3": 0x33, "4": 0x34, "5": 0x35, "6": 0x36, "7": 0x37, "8": 0x38, "9": 0x39,'F1': 112, 'F2': 113, 'F3': 114, 'F4': 115, 'F5': 116, 'F6': 117, 'F7': 118, 'F8': 119,'F9': 120, 'F10': 121, 'F11': 122, 'F12': 123, 'F13': 124, 'F14': 125, 'F15': 126, 'F16': 127,"A": 65, "B": 66, "C": 67, "D": 68, "E": 69, "F": 70, "G": 71, "H": 72, "I": 73, "J": 74,"K": 75, "L": 76, "M": 77, "N": 78, "O": 79, "P": 80, "Q": 81, "R": 82, "S": 83, "T": 84,"U": 85, "V": 86, "W": 87, "X": 88, "Y": 89, "Z": 90,'BACKSPACE': 8, 'TAB': 9, 'TABLE': 9, 'CLEAR': 12,'ENTER': 13, 'SHIFT': 16, 'CTRL': 17,'CONTROL': 17, 'ALT': 18, 'ALTER': 18, 'PAUSE': 19, 'BREAK': 19, 'CAPSLK': 20, 'CAPSLOCK': 20, 'ESC': 27,' ': 32, 'SPACEBAR': 32, 'PGUP': 33, 'PAGEUP': 33, 'PGDN': 34, 'PAGEDOWN': 34, 'END': 35, 'HOME': 36,'LEFT': 37, 'UP': 38, 'RIGHT': 39, 'DOWN': 40, 'SELECT': 41, 'PRTSC': 42, 'PRINTSCREEN': 42, 'SYSRQ': 42,'SYSTEMREQUEST': 42, 'EXECUTE': 43, 'SNAPSHOT': 44, 'INSERT': 45, 'DELETE': 46, 'HELP': 47, 'WIN': 91,'WINDOWS': 91, 'NMLK': 144,'.':0xBE,'NUMLK': 144, 'NUMLOCK': 144, 'SCRLK': 145,'[': 219, ']': 221, '+': 107, '-': 109}num = 5
# 定义一下你要输入的命令字符串
cmds = [f'python node.py {num} n{i + 1}' for i in range(num)]
cmds.append(f'python tester.py {num}')
for cmd in cmds:# 打开cmdsubprocess.Popen('start C:\windows\system32\cmd.exe', shell=True)# sleep一下,因为windows11打开cmd比较慢,为了防止界面还没出现而误触,这样做一下比较保险sleep(0.2)#查找打开的窗口,findwindow(x,y)x是类别名,y是窗口标题n=win32gui.FindWindow('ConsoleWindowClass', None)# 置顶窗口p=win32gui.SetForegroundWindow(n)for chr in cmd:# print(chr.upper())# 按下按键win32api.keybd_event(key_map[chr.upper()], 0, 0, 0)win32api.keybd_event(13,0,0,0) #enterwin32api.keybd_event(13,0,win32con.KEYEVENTF_KEYUP,0)
二、效果展示
如上图所示,我们就实现了打开多个命令窗口,并执行了我们想输入的指令,同样地,我们也可以用类似的方式打开其他的软件等。
三、存在问题
1. ImportError: DLL load failed while importing win32api: 找不到指定的模块。
这种一般就是win32api的版本太高了,一般需要低于302版本,可以用225或者226之类的低版本,解决方案如下:
-
pip install pypiwin32
-
pip install pywin32==225
2. 窗口打开了但是不输入命令
这种一般是因为没有捕获到窗口句柄或者是因为打开窗口太慢了,解决方案有两种:
- 使用微软的spy++工具来查看一下你即将打开的窗口的类名,以windows terminal为例:
使用spy++中的查找功能,我们可以指导对应程序的类和标题,帮助我们使用findwindow函数定位句柄,这里可以看出,cmd的类名是ConsoleWindowClass,但是部分笔记本的win11上的cmd并不是这个类名,所有需要注意!!!!
- 窗口打开的太慢
这个时候修改一下sleep的时间(单位是s),给窗口打开留点时间。