Send_picture_automatically/stop_scheduler.py
teddy f96d1eb08d feat: 更新配置和增强日志记录功能
- 修改config.py中的文件路径和定时发送时间
- 在各个脚本中添加日志记录功能,提升错误追踪和调试能力
- 更新README.md,详细说明程序功能和使用方法
- 重构scheduler.py、sendmsg.py、send_openmsg.py和send_filemsg.py,增强代码可读性和可维护性
2025-08-21 15:22:55 +08:00

179 lines
8.4 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import subprocess
import sys
import os
import psutil
from pathlib import Path
from logger_config import setup_logger
# 设置日志记录器
logger = setup_logger('stop_scheduler')
def stop_scheduler():
"""停止定时任务进程和相关的sendmsg.py进程"""
logger.info("=" * 50)
logger.info("开始停止定时任务进程")
logger.info("=" * 50)
stopped_count = 0
current_dir = str(Path(__file__).parent)
logger.info(f"当前工作目录: {current_dir}")
# 方法0: 从PID文件中读取进程ID
pid_file = Path(__file__).parent / "scheduler_pid.txt"
if pid_file.exists():
logger.info(f"发现PID文件: {pid_file}")
try:
with open(pid_file, 'r') as f:
pid = int(f.read().strip())
logger.info(f"从PID文件中读取到进程ID: {pid}")
try:
process = psutil.Process(pid)
logger.info(f"找到进程: PID={pid}, 名称={process.name()}")
logger.info(f"进程命令行: {' '.join(process.cmdline())}")
process.terminate()
logger.info(f"已发送终止信号给进程 PID={pid}")
try:
process.wait(timeout=5) # 等待进程正常结束
logger.info(f"进程 PID={pid} 已正常终止")
except psutil.TimeoutExpired:
logger.warning(f"进程 PID={pid} 未在5秒内终止强制结束")
process.kill()
logger.info(f"已强制结束进程 PID={pid}")
stopped_count += 1
# 删除PID文件
pid_file.unlink()
logger.info("PID文件已删除")
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess) as e:
logger.warning(f"PID文件中的进程 {pid} 已不存在或无法访问: {str(e)}")
# 删除过期的PID文件
pid_file.unlink()
logger.info("过期的PID文件已删除")
except Exception as e:
logger.error(f"从PID文件读取进程ID失败: {str(e)}")
logger.error(f"错误类型: {type(e).__name__}")
else:
logger.info("未找到PID文件尝试其他方法查找进程...")
try:
# 方法1: 使用psutil精确查找进程
logger.info("使用psutil查找相关进程...")
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:
logger.info(f"找到目标进程: PID={proc.info['pid']}")
logger.info(f"进程名称: {proc.info['name']}")
logger.info(f"命令行: {cmdline_str}")
try:
proc.terminate()
logger.info(f"已发送终止信号给进程 PID={proc.info['pid']}")
try:
proc.wait(timeout=5) # 等待进程正常结束
logger.info(f"进程 PID={proc.info['pid']} 已正常终止")
except psutil.TimeoutExpired:
logger.warning(f"进程 PID={proc.info['pid']} 未在5秒内终止强制结束")
proc.kill()
logger.info(f"已强制结束进程 PID={proc.info['pid']}")
stopped_count += 1
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess) as e:
logger.warning(f"进程 {proc.info['pid']} 已不存在或无法访问: {str(e)}")
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess) as e:
logger.debug(f"跳过进程 {proc.info.get('pid', 'unknown')}: {str(e)}")
continue
except ImportError:
logger.warning("psutil模块未安装使用备用方法...")
# 方法2: 备用方法 - 改进的tasklist方式
try:
logger.info("使用wmic命令查找进程...")
# 获取详细的进程信息
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')
for line in lines[1:]: # 跳过标题行
if line.strip() and ('scheduler.py' in line or 'sendmsg.py' in line) and current_dir in line:
logger.info(f"找到目标进程: {line}")
# 提取PID
parts = line.split(',')
if len(parts) >= 2:
pid = parts[-1].strip()
if pid.isdigit():
logger.info(f"正在终止进程 PID={pid}")
subprocess.run(['taskkill', '/F', '/PID', pid], check=True)
logger.info(f"已终止进程 PID={pid}")
stopped_count += 1
except subprocess.CalledProcessError as e:
logger.error(f"wmic方法执行失败: {e}")
# 方法3: 最后的备用方案
try:
logger.info("使用tasklist命令查找进程...")
result = subprocess.run(['tasklist', '/FI', 'IMAGENAME eq pythonw.exe', '/FO', 'CSV'],
capture_output=True, text=True)
if 'pythonw.exe' in result.stdout:
logger.warning("警告: 找到pythonw.exe进程但无法确定是否为目标进程")
logger.warning("建议手动检查进程列表")
logger.info("进程列表:")
logger.info(result.stdout)
response = input("是否强制结束所有pythonw.exe进程(y/N): ")
if response.lower() == 'y':
logger.info("正在强制结束所有pythonw.exe进程...")
subprocess.run(['taskkill', '/F', '/IM', 'pythonw.exe'], check=True)
logger.info("已强制结束所有pythonw.exe进程")
stopped_count += 1
except subprocess.CalledProcessError as e:
logger.error(f"最后备用方案失败: {e}")
# 总结报告
logger.info("=" * 50)
if stopped_count > 0:
logger.info(f"成功停止了 {stopped_count} 个定时任务相关进程(scheduler.py或sendmsg.py)")
else:
logger.info("未找到运行中的定时任务相关进程(scheduler.py或sendmsg.py)")
logger.info("=" * 50)
# 额外检查:查看是否还有相关进程
logger.info("检查剩余进程...")
try:
result = subprocess.run(['tasklist', '/FI', 'IMAGENAME eq pythonw.exe'],
capture_output=True, text=True)
if 'pythonw.exe' in result.stdout:
logger.info("仍有pythonw.exe进程在运行:")
logger.info(result.stdout)
else:
logger.info("没有发现pythonw.exe进程")
except Exception as e:
logger.warning(f"检查剩余进程失败: {str(e)}")
if __name__ == "__main__":
try:
stop_scheduler()
logger.info("程序执行完成")
except Exception as e:
logger.error(f"程序执行过程中出现未捕获的异常: {str(e)}")
logger.error(f"异常类型: {type(e).__name__}")
import traceback
logger.error(f"异常堆栈: {traceback.format_exc()}")
exit(1)