- 在service_runner.py中添加进程ID记录功能 - 增强stop_scheduler.py以同时处理scheduler.py和sendmsg.py进程 - 修改sendmsg.py增加重试机制 - 更新配置文件路径和执行时间
117 lines
5.2 KiB
Python
117 lines
5.2 KiB
Python
import subprocess
|
||
import sys
|
||
import os
|
||
import psutil
|
||
from pathlib import Path
|
||
|
||
def stop_scheduler():
|
||
"""停止定时任务进程和相关的sendmsg.py进程"""
|
||
stopped_count = 0
|
||
|
||
# 方法0: 从PID文件中读取进程ID
|
||
pid_file = Path(__file__).parent / "scheduler_pid.txt"
|
||
if pid_file.exists():
|
||
try:
|
||
with open(pid_file, 'r') as f:
|
||
pid = int(f.read().strip())
|
||
|
||
try:
|
||
process = psutil.Process(pid)
|
||
print(f"从PID文件中找到进程: PID={pid}")
|
||
process.terminate()
|
||
process.wait(timeout=5) # 等待进程正常结束
|
||
print(f"已终止进程 PID={pid}")
|
||
stopped_count += 1
|
||
# 删除PID文件
|
||
pid_file.unlink()
|
||
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
|
||
print(f"PID文件中的进程 {pid} 已不存在或无法访问")
|
||
# 删除过期的PID文件
|
||
pid_file.unlink()
|
||
except Exception as e:
|
||
print(f"从PID文件读取进程ID失败: {str(e)}")
|
||
else:
|
||
print("未找到PID文件,尝试其他方法查找进程...")
|
||
|
||
|
||
try:
|
||
# 方法1: 使用psutil精确查找进程
|
||
current_dir = str(Path(__file__).parent)
|
||
|
||
for proc in psutil.process_iter(['pid', 'name', 'cmdline']):
|
||
try:
|
||
if proc.info['name'] in ['python.exe', 'pythonw.exe']:
|
||
cmdline = proc.info['cmdline']
|
||
if cmdline and len(cmdline) > 1:
|
||
# 检查是否是我们的scheduler.py或sendmsg.py进程
|
||
cmdline_str = ' '.join(cmdline)
|
||
if ('scheduler.py' in cmdline_str or 'sendmsg.py' in cmdline_str) and current_dir in cmdline_str:
|
||
print(f"找到进程: PID={proc.info['pid']}, 命令行={' '.join(cmdline)}")
|
||
proc.terminate()
|
||
proc.wait(timeout=5) # 等待进程正常结束
|
||
print(f"已终止进程 PID={proc.info['pid']}")
|
||
stopped_count += 1
|
||
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
|
||
continue
|
||
|
||
except ImportError:
|
||
print("psutil模块未安装,使用备用方法...")
|
||
# 方法2: 备用方法 - 改进的tasklist方式
|
||
try:
|
||
# 获取详细的进程信息
|
||
result = subprocess.run(['wmic', 'process', 'where', 'name="pythonw.exe"', 'get', 'ProcessId,CommandLine', '/format:csv'],
|
||
capture_output=True, text=True, encoding='gbk')
|
||
|
||
lines = result.stdout.strip().split('\n')
|
||
current_dir = str(Path(__file__).parent)
|
||
|
||
for line in lines[1:]: # 跳过标题行
|
||
if line.strip() and ('scheduler.py' in line or 'sendmsg.py' in line) and current_dir in line:
|
||
# 提取PID
|
||
parts = line.split(',')
|
||
if len(parts) >= 2:
|
||
pid = parts[-1].strip()
|
||
if pid.isdigit():
|
||
subprocess.run(['taskkill', '/F', '/PID', pid], check=True)
|
||
print(f"已终止进程 PID={pid}")
|
||
stopped_count += 1
|
||
|
||
except subprocess.CalledProcessError as e:
|
||
print(f"备用方法执行失败: {e}")
|
||
|
||
# 方法3: 最后的备用方案
|
||
try:
|
||
result = subprocess.run(['tasklist', '/FI', 'IMAGENAME eq pythonw.exe', '/FO', 'CSV'],
|
||
capture_output=True, text=True)
|
||
|
||
if 'pythonw.exe' in result.stdout:
|
||
print("警告: 找到pythonw.exe进程,但无法确定是否为目标进程")
|
||
response = input("是否强制结束所有pythonw.exe进程?(y/N): ")
|
||
if response.lower() == 'y':
|
||
subprocess.run(['taskkill', '/F', '/IM', 'pythonw.exe'], check=True)
|
||
print("已强制结束所有pythonw.exe进程")
|
||
stopped_count += 1
|
||
|
||
except subprocess.CalledProcessError as e:
|
||
print(f"最后备用方案失败: {e}")
|
||
|
||
if stopped_count > 0:
|
||
print(f"成功停止了 {stopped_count} 个定时任务相关进程(scheduler.py或sendmsg.py)")
|
||
else:
|
||
print("未找到运行中的定时任务相关进程(scheduler.py或sendmsg.py)")
|
||
|
||
# 额外检查:查看是否还有相关进程
|
||
print("\n检查剩余进程...")
|
||
try:
|
||
result = subprocess.run(['tasklist', '/FI', 'IMAGENAME eq pythonw.exe'],
|
||
capture_output=True, text=True)
|
||
if 'pythonw.exe' in result.stdout:
|
||
print("仍有pythonw.exe进程在运行:")
|
||
print(result.stdout)
|
||
else:
|
||
print("没有发现pythonw.exe进程")
|
||
except:
|
||
pass
|
||
|
||
if __name__ == "__main__":
|
||
stop_scheduler() |