目的
- 通过os.system(f’start cmd.exe /K ipconfig’)启动命令行执行任意命令
- 通过win32gui的EnumWindows或FindWindows获取命令行窗口的句柄
- 通过命令行窗口句柄实现对命令行窗口的后续操作
现象及代码
- 代码
# -*- coding:utf-8 -*-
import os
import time
import win32gui
os.system(f'start cmd.exe /K ipconfig')
hwnd_title = dict()
hwnd_cmds = []
def get_all_hwnd(hwnd, mouse):
if win32gui.IsWindow(hwnd) and win32gui.IsWindowEnabled(hwnd) and win32gui.IsWindowVisible(hwnd):
hwnd_title.update({hwnd: win32gui.GetWindowText(hwnd)})
win32gui.EnumWindows(get_all_hwnd, 0)
# print(hwnd_title) # 调试用
cmd_str = r"C:\Windows\system32\cmd.exe"
for h, t in hwnd_title.items():
if cmd_str in str(t):
hwnd_cmds.append(h)
print(hwnd_cmds)
运行代码后结果如下, 之前试用FindWindows也出现过同样的情况:
解决过程及方法
- 首先确认函数调用的问题:
一开始用的是FindWindow(“class”,strTitle)函,
查阅资料后得知调用方法为:
FindWindow(“ConsoleWindowClass”, r"C:\Windows\system32\cmd.exe")
结果:发现还是偶现获取到空句柄的情况
- 确认窗口标题字符是否准确
查阅资料后发现窗口标题忽略大小写,没有问题;
后续无意间用ping命令时发现在试用os.system运行命令的过程中,会在命令行窗口标题上自动加上命令,即标题变成:
C:\Windows\system32\cmd.exe - ping 111.111.111.111 -n 30
运行完之后窗口标题又会变回:
C:\Windows\system32\cmd.exe
- 解决方案:
使用EnumWindows枚举所有然后过滤,即:
def get_all_hwnd(hwnd, mouse):
if win32gui.IsWindow(hwnd) and win32gui.IsWindowEnabled(hwnd) and win32gui.IsWindowVisible(hwnd):
hwnd_title.update({hwnd: win32gui.GetWindowText(hwnd)})
win32gui.EnumWindows(get_all_hwnd, 0)
cmd_str = r"C:\Windows\system32\cmd.exe"
for h, t in hwnd_title.items():
if cmd_str in str(t):
hwnd_cmds.append(h)
结果:还会出现句柄为空的情况
- 命令行窗口延迟
用iperf命令时发现命令行运行有延迟
于是在用os.system(f’start cmd.exe /K **')启动命令行之后,加了一个系统延时,即:
time.sleep(2)
结果:成功解决
原因分析与结果评估
- 原因分析:
可能时系统执行命令先后的问题,可能涉及到系统进程并行问题
- 结果评估:
能稳定获取句柄,但没从根本解决问题,后续考虑python线程池的问题