目录
关闭进程和子进程:
bash
taskkill /F /IM bambu-studio.exe /T
参数解释:
/F:强制终止进程。
/IM:指定要终止的进程映像名称。
/T:终止指定的进程及其启动的所有子进程。
不动代码也能立刻验证
-
用 Process Explorer / procdump 看挂在哪个线程上,直接就能看出是不是
m_check_cert_thread、worker_还是boost::log内部线程:cmd
procdump -ma -e 1 BambuStudio.exe -
在弹"无法响应"对话框时,把窗口强制关掉,看 cmd 是否立即返回 prompt。如果立即返回,就是 GUI 主循环没退出;如果还要等几秒到几十秒,就是后台线程在等你。
python监控进程:
如果发现两个以上进程,关闭重启
python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import psutil
import time
import os
import sys
import logging
from datetime import datetime
from typing import List, Dict, Optional
import subprocess
import argparse
import ctypes
from ctypes import wintypes
# 配置日志
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('bambu_monitor.log',encoding='utf-8'),
logging.StreamHandler()
]
)
logger = logging.getLogger(__name__)
# Bambu Studio 可执行文件路径
BAMBU_EXE_PATH = r"D:\soft\RelWithDebInfo\bambu-studio.exe"
class WindowsProcessKiller:
"""Windows 进程强制终止工具"""
@staticmethod
def kill_all_bambu_processes() -> int:
"""使用 taskkill 强制终止所有 Bambu Studio 进程"""
try:
logger.info("执行: taskkill /F /IM bambu-studio.exe /T")
result = subprocess.run(
['taskkill', '/F', '/IM', 'bambu-studio.exe', '/T'],
capture_output=True,
text=True,
timeout=10
)
# taskkill 返回 0 表示成功,128 表示没有找到进程
if result.returncode == 0:
logger.info("✅ taskkill 成功终止所有 Bambu Studio 进程")
return 1
elif result.returncode == 128:
logger.info("没有找到 Bambu Studio 进程")
return 0
else:
logger.warning(f"taskkill 返回码: {result.returncode}, 输出: {result.stderr}")
return 0
except subprocess.TimeoutExpired:
logger.error("taskkill 超时")
return 0
except Exception as e:
logger.error(f"taskkill 异常: {e}")
return 0
@staticmethod
def launch_bambu_studio() -> bool:
"""启动 Bambu Studio"""
try:
if not os.path.exists(BAMBU_EXE_PATH):
logger.error(f"找不到 Bambu Studio: {BAMBU_EXE_PATH}")
return False
logger.info(f"启动 Bambu Studio: {BAMBU_EXE_PATH}")
subprocess.Popen([BAMBU_EXE_PATH], shell=True)
logger.info("✅ Bambu Studio 已启动")
return True
except Exception as e:
logger.error(f"启动 Bambu Studio 失败: {e}")
return False
class BambooStudioMonitor:
"""Bambu Studio 进程监控器"""
def __init__(self,
process_name: str = "bambu-studio.exe",
check_interval: int = 60):
self.process_name = process_name
self.check_interval = check_interval
self.stopped = False
self.killer = WindowsProcessKiller()
def get_bambu_processes(self) -> List[psutil.Process]:
"""获取所有 Bambu Studio 进程"""
processes = []
for proc in psutil.process_iter(['pid', 'name', 'create_time', 'cpu_percent', 'memory_info', 'cmdline']):
try:
if proc.info['name'] and self.process_name.lower() in proc.info['name'].lower():
processes.append(proc)
except (psutil.NoSuchProcess, psutil.AccessDenied):
continue
return processes
def get_process_age_minutes(self, proc: psutil.Process) -> float:
"""获取进程运行时间(分钟)"""
try:
create_time = proc.create_time()
age_seconds = time.time() - create_time
return age_seconds / 60
except (psutil.NoSuchProcess, psutil.AccessDenied):
return 0
def kill_all_bambu_processes(self) -> int:
"""终止所有 Bambu Studio 进程"""
return WindowsProcessKiller.kill_all_bambu_processes()
def launch_bambu_studio(self) -> bool:
"""启动 Bambu Studio"""
return WindowsProcessKiller.launch_bambu_studio()
def run_once(self) -> Dict:
"""执行一次检查"""
logger.info("开始检查 Bambu Studio 进程...")
processes = self.get_bambu_processes()
process_count = len(processes)
# 打印进程详情
for proc in processes:
try:
pid = proc.pid
age_minutes = self.get_process_age_minutes(proc)
cpu_percent = proc.cpu_percent(interval=0.1)
memory_mb = proc.memory_info().rss / 1024 / 1024
logger.info(f" PID={pid}, 运行={age_minutes:.1f}分钟, CPU={cpu_percent:.1f}%, 内存={memory_mb:.1f}MB")
except:
pass
if process_count == 0:
logger.info("未找到 Bambu Studio 进程,启动新进程...")
self.launch_bambu_studio()
return {"status": "launched", "killed": 0}
logger.info(f"找到 {process_count} 个 Bambu Studio 进程")
# 如果进程数 >= 2,全部杀掉然后重启
if process_count >= 2:
logger.warning(f"⚠️ 检测到 {process_count} 个进程(超过1个),执行清理并重启...")
# 使用 taskkill /F /IM 强制杀掉所有进程
killed = self.kill_all_bambu_processes()
# 等待进程完全退出
logger.info("等待进程退出...")
time.sleep(2)
# 重新启动
logger.info("重新启动 Bambu Studio...")
self.launch_bambu_studio()
return {"status": "killed_and_restarted", "killed": killed}
# 只有1个进程,正常运行
logger.info("✅ 只有1个进程,正常运行中")
return {"status": "normal", "total": 1, "killed": 0}
def run_loop(self):
"""持续运行监控"""
logger.info(f"开始持续监控,检查间隔: {self.check_interval}秒")
logger.info(f"检测到 2 个以上进程时会自动清理并重启")
while not self.stopped:
try:
self.run_once()
except Exception as e:
logger.error(f"监控循环出错: {e}")
# 等待下一次检查
for _ in range(self.check_interval):
if self.stopped:
break
time.sleep(1)
logger.info("监控已停止")
def stop(self):
"""停止监控"""
self.stopped = True
def main():
"""主函数"""
parser = argparse.ArgumentParser(
description="Bambu Studio 多进程监控器 - 检测到2个以上进程时自动清理重启"
)
parser.add_argument("--once", action="store_true", help="只运行一次检查")
parser.add_argument("--list", action="store_true", help="列出所有Bambu进程")
parser.add_argument("--interval", type=int, default=60, help="检查间隔秒数(默认60)")
args = parser.parse_args()
# 列出所有Bambu进程
if args.list:
monitor = BambooStudioMonitor()
processes = monitor.get_bambu_processes()
if not processes:
print("未找到 Bambu Studio 进程")
return
print(f"\n找到 {len(processes)} 个 Bambu Studio 进程:")
print("-" * 70)
for proc in processes:
try:
pid = proc.pid
create_time = datetime.fromtimestamp(proc.create_time()).isoformat()
age = monitor.get_process_age_minutes(proc)
cpu = proc.cpu_percent(interval=0.1)
memory = proc.memory_info().rss / 1024 / 1024
status = proc.status()
print(f"PID: {pid:6d} | 创建: {create_time}")
print(f" 运行: {age:.1f}分钟 | CPU: {cpu:.1f}% | 内存: {memory:.1f}MB | 状态: {status}")
print("-" * 70)
except:
pass
return
# 创建监控器
monitor = BambooStudioMonitor(
process_name="bambu-studio.exe",
check_interval=args.interval
)
# 运行
if args.once:
result = monitor.run_once()
print(f"\n检查结果: {result}")
else:
try:
print("按 Ctrl+C 停止监控")
print(f"检查间隔: {args.interval}秒")
monitor.run_loop()
except KeyboardInterrupt:
monitor.stop()
print("\n监控已停止")
if __name__ == "__main__":
main()