一、前置说明
在自动化过程中,经常需要在命令行中执行一些操作,比如启动应用、查杀应用等,因此可以封装成一个CommandExecutor来专门处理这些事情。
二、操作步骤
# cmd_util.py
import logging
import os
import platform
import shutil
import subprocess
import psutil
logger = logging.getLogger(__name__)
class CommandExecutor:
@staticmethod
def execute_command(command):
"""
subprocess.run() 方法用于执行命令并等待其完成,然后返回一个 CompletedProcess 对象,该对象包含执行结果的属性。
它适用于需要等待命令完成并获取结果的情况。
"""
try:
result = subprocess.run(command, shell=True, capture_output=True, text=True)
if result.returncode == 0:
return result.stdout.strip()
else:
return result.stderr.strip()
except Exception as e:
return str(e)
@classmethod
def kill_processes_with_name(cls, name):
"""
查杀窗口名称包含 name 的所有进程,支持模拟匹配
"""
try:
if platform.system() == 'Windows':
# Windows系统使用tasklist和findstr命令来获取包含特定字符串的窗口进程列表
command = f'tasklist /V /FO CSV | findstr /C:"{name}"'
output = cls.execute_command(command)
if output:
# 遍历输出的进程列表
for line in output.splitlines():
# 解析进程信息
process_info = line.split(",")
process_name = process_info[0].strip('"')
process_id = process_info[1].strip('"')
# 先尝试关父进程,解决:关掉uiautomatorview或appium server 之后, 会留下一个无用的cmd的窗口
try:
# 获取父进程
parent_process = psutil.Process(int(process_id)).parent()
# 终止父进程(CMD窗口)
kill_parent_command = f"taskkill /F /T /PID {parent_process.pid}"
cls.execute_command(kill_parent_command)
except:
pass
# 如果没有父进程,则直接关闭子进程;如果父进程已关闭,子进程会消失,也try catch 一下
try:
# 终止进程
kill_command = f"taskkill /F /T /PID {process_id}"
cls.execute_command(kill_command)
# 记录日志
logger.info(f"Stopped process '{process_name}' with ID '{process_id}'")
except:
pass
else:
logger.info(f"No processes found with window name containing '{name}'")
else:
# 其他操作系统使用wmctrl命令获取包含特定字符串的窗口列表
command = f"wmctrl -l | grep {name}"
window_list = cls.execute_command(command)
if window_list:
# 遍历输出的窗口列表
for line in window_list.splitlines():
# 解析窗口信息
window_info = line.split()
window_id = window_info[0]
# 关闭窗口
os.system(f"wmctrl -ic {window_id}")
# 记录日志
logger.info(f"Stopped processes with window name containing '{name}'")
else:
logger.info(f"No processes found with window name containing '{name}'")
except Exception as e:
logger.warning(f"Error: {str(e)}")
cmd_executor = CommandExecutor()
cmd = cmd_executor
三、Demo验证
以关闭多开的两个夜神模拟器,来测试代码,顺利关闭:
if __name__ == '__main__':
import logging
logging.basicConfig(level=logging.DEBUG)
print(cmd.kill_processes_with_name('夜神'))
欢迎技术交流: