用python制作一个打印队列自动清理工具
用python制作一个打印队列自动清理工具内容选项包含如下 1.启动监控模式 2.理解清理所有卡住的打印任务 3.重置所有打印队列(清空所有任务) 4.查看当前打印队列状态 5.配置参数 6.退出 第一步运行代码前要先在python终端安装pywin32库 pip install pywin32 否则会报错ModuleNotFoundError: No module named 'win32print' python代码 import time import threading import win32print import win32con import sys # ---------- 全局配置 ---------- config = { "monitor_interval": 10,# 监控间隔(秒) "stuck_timeout": 60,# 认为任务卡住的超时时间(秒) "auto_clean_stuck": True# 监控模式下是否自动清理 } monitor_running = False monitor_thread = None # ---------- 安全获取打印机列表 ---------- def get_all_printers(): """安全获取所有本地及网络打印机的名称列表""" printers = [] try: printers_enum = win32print.EnumPrinters( win32print.PRINTER_ENUM_LOCAL | win32print.PRINTER_ENUM_CONNECTIONS, None, 2 ) for p in printers_enum: if len(p) >= 3: printers.append(p[2])# 打印机名称在索引2 elif len(p) > 0: printers.append(p[0])# 备用:取第一个元素 except Exception as e: print(f"获取打印机列表时出错: {e}") return printers # ---------- 辅助函数 ---------- def get_job_submitted_time(job): try: submitted = job.get('submitted') if submitted and len(submitted) >= 6: return time.mktime(submitted) except: pass return time.time() def is_job_stuck(job): status = job.get('Status', 0) # 已打印的任务不算卡住 if status & win32con.JOB_STATUS_PRINTED: return False stuck_flags = (win32con.JOB_STATUS_PAUSED | win32con.JOB_STATUS_ERROR | win32con.JOB_STATUS_OFFLINE | win32con.JOB_STATUS_PAPEROUT | win32con.JOB_STATUS_BLOCKED_DEVQ) if status & stuck_flags: return True # 长时间未完成 submitted_time = get_job_submitted_time(job) if time.time() - submitted_time > config["stuck_timeout"]: return True return False def clean_stuck_jobs(): cleaned = 0 printers = get_all_printers() if not printers: print("未找到任何打印机。") return 0 for printer_name in printers: try: hprinter = win32print.OpenPrinter(printer_name) jobs = win32print.EnumJobs(hprinter, 0, -1, 1) for job in jobs: if is_job_stuck(job): try: win32print.SetJob(hprinter, job['JobId'], 0, None, win32con.JOB_CONTROL_DELETE) print(f"已删除卡住任务: 打印机 [{printer_name}] 任务ID {job['JobId']}") cleaned += 1 except Exception as e: print(f"删除任务失败 (打印机 {printer_name}, 任务 {job['JobId']}): {e}") win32print.ClosePrinter(hprinter) except Exception as e: print(f"无法打开打印机 {printer_name}: {e}") return cleaned def clear_all_jobs(): printers = get_all_printers() if not printers: print("未找到任何打印机。") return for printer_name in printers: try: hprinter = win32print.OpenPrinter(printer_name) jobs = win32print.EnumJobs(hprinter, 0, -1, 1) for job in jobs: try: win32print.SetJob(hprinter, job['JobId'], 0, None, win32con.JOB_CONTROL_DELETE) print(f"已删除任务: 打印机 [{printer_name}] 任务ID {job['JobId']}") except Exception as e: print(f"删除任务失败 (打印机 {printer_name}, 任务 {job['JobId']}): {e}") win32print.ClosePrinter(hprinter) except Exception as e: print(f"无法打开打印机 {printer_name}: {e}") def show_queue_status(): printers = get_all_printers() if not printers: print("未找到任何打印机。") return for printer_name in printers: try: hprinter = win32print.OpenPrinter(printer_name) printer_info = win32print.GetPrinter(hprinter, 2) print(f"\n打印机: {printer_name}") print(f"状态: {printer_info.get('Status', 0)} (参考: 0=就绪, 1=暂停, 2=错误, 3=未知)") jobs = win32print.EnumJobs(hprinter, 0, -1, 1) if jobs: print(f"任务列表 (共 {len(jobs)} 个):") for job in jobs: status = job.get('Status', 0) status_str = [] if status & win32con.JOB_STATUS_PAUSED: status_str.append("暂停") if status & win32con.JOB_STATUS_ERROR: status_str.append("错误") if status & win32con.JOB_STATUS_OFFLINE: status_str.append("脱机") if status & win32con.JOB_STATUS_PAPEROUT: status_str.append("缺纸") if status & win32con.JOB_STATUS_PRINTED: status_str.append("已打印") if status & win32con.JOB_STATUS_DELETING: status_str.append("删除中") if not status_str: status_str.append("正常") print(f"- 任务ID: {job['JobId']}, 文档: {job.get('pDocument', '未知')}, 状态: {', '.join(status_str)}") else: print("队列为空。") win32print.ClosePrinter(hprinter) except Exception as e: print(f"无法访问打印机 {printer_name}: {e}") def monitor_loop(): global monitor_running while monitor_running: try: if config["auto_clean_stuck"]: print("\n[监控] 正在检查卡住的任务...") count = clean_stuck_jobs() if count > 0: print(f"[监控] 已清理 {count} 个卡住任务。") else: print("[监控] 没有发现卡住任务。") else: # 仅检查,不清理 print("\n[监控] 正在检查卡住任务(仅显示)...") printers = get_all_printers() stuck_count = 0 for printer_name in printers: try: hprinter = win32print.OpenPrinter(printer_name) jobs = win32print.EnumJobs(hprinter, 0, -1, 1) for job in jobs: if is_job_stuck(job): print(f"卡住任务: 打印机 {printer_name}, 任务ID {job['JobId']}") stuck_count += 1 win32print.ClosePrinter(hprinter) except: pass if stuck_count == 0: print("[监控] 未发现卡住任务。") else: print(f"[监控] 发现 {stuck_count} 个卡住任务(未自动清理)。") except Exception as e: print(f"[监控] 发生错误: {e}") time.sleep(config["monitor_interval"]) def start_monitor(): global monitor_running, monitor_thread if monitor_running: print("监控模式已在运行中。") return monitor_running = True monitor_thread = threading.Thread(target=monitor_loop, daemon=True) monitor_thread.start() print("监控模式已启动。") def stop_monitor(): global monitor_running if not monitor_running: print("监控模式未运行。") return monitor_running = False print("正在停止监控模式...") if monitor_thread and monitor_thread.is_alive(): monitor_thread.join(timeout=2) print("监控模式已停止。") def configure(): print("\n当前配置:") print(f"监控间隔: {config['monitor_interval']} 秒") print(f"卡住超时: {config['stuck_timeout']} 秒") print(f"自动清理卡住任务: {'是' if config['auto_clean_stuck'] else '否'}") print("\n请输入新值(直接回车保留原值):") try: interval = input(f"监控间隔 (秒) [{config['monitor_interval']}]: ").strip() if interval: config['monitor_interval'] = int(interval) timeout = input(f"卡住超时 (秒) [{config['stuck_timeout']}]: ").strip() if timeout: config['stuck_timeout'] = int(timeout) auto = input(f"自动清理卡住任务 (y/n) [{ 'y' if config['auto_clean_stuck'] else 'n' }]: ").strip().lower() if auto == 'y': config['auto_clean_stuck'] = True elif auto == 'n': config['auto_clean_stuck'] = False print("配置已更新。") except ValueError: print("输入无效,配置未变更。") def main_menu(): while True: print("\n" + "="*50) print("打印队列自动清理工具") print("="*50) print("1. 启动监控模式") print("2. 立即清理所有卡住的打印任务") print("3. 重置所有打印队列(清空所有任务)") print("4. 查看当前打印队列状态") print("5. 配置参数") print("6. 退出") choice = input("请选择操作 [1-6]: ").strip() if choice == "1": start_monitor() elif choice == "2": count = clean_stuck_jobs() print(f"清理完成,共删除了 {count} 个卡住任务。") elif choice == "3": confirm = input("警告:此操作将删除所有打印队列中的所有任务,是否继续?(y/n): ").strip().lower() if confirm == 'y': clear_all_jobs() print("所有打印队列已清空。") else: print("操作取消。") elif choice == "4": show_queue_status() elif choice == "5": configure() elif choice == "6": if monitor_running: stop_monitor() print("感谢使用,再见!") sys.exit(0) else: print("无效选项,请重新输入。") if __name__ == "__main__": try: import win32print except ImportError: print("错误:未安装 pywin32 模块。请运行: pip install pywin32") sys.exit(1) main_menu()
python文件如何打包成exe格式
1. 安装 PyInstaller 首先确保你的电脑上已安装 Python 环境,然后打开命令提示符(CMD)或 PowerShell,执行: bash pip install pyinstaller 如果你的网络较慢,可以使用国内镜像加速: bash pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pyinstaller 2. 准备打包脚本 假设你的 Python 脚本文件名为 print_cleaner.py。 注意:在打包前,请先在命令行中运行一次脚本,确保它能正常启动,没有语法错误或缺失的依赖。 例如: bash python print_cleaner.py 如果出现 ModuleNotFoundError,说明缺少某些库(如 pywin32),需要先安装: bash pip install pywin32 3. 使用 PyInstaller 打包 打开命令提示符,切换到脚本所在的目录,然后执行以下基本打包命令: bash pyinstaller --onefile --console print_cleaner.py 参数说明: --onefile:将所有内容打包成一个单独的 .exe 文件(默认是多文件模式)。 --console:运行 exe 时显示控制台窗口(适合命令行工具)。如果你的工具需要显示 GUI 界面,可以改为 --windowed 隐藏控制台,但你的工具是控制台菜单,所以保留控制台。 执行后,PyInstaller 会开始分析并打包。完成后,生成的 .exe 文件位于 dist 文件夹中。 4. 高级打包选项 (1)添加图标 如果你想给 exe 文件设置自定义图标,使用 --icon 参数,例如: bash pyinstaller --onefile --console --icon=myicon.ico print_cleaner.py 图标文件需要是 .ico 格式,其他格式(如 .png)需要先转换。 (2)指定输出目录 默认输出到 dist 文件夹,可以使用 --distpath 指定其他路径。 (3)包含额外文件 如果脚本需要读取配置文件或资源文件,可以使用 --add-data 参数。例如: bash pyinstaller --onefile --console --add-data "config.ini;." print_cleaner.py Windows 下用分号 ; 分隔源路径和目标路径。 多个 --add-data 可以重复使用
python生成的exe格式添加ico图标方法
1.访问阿里巴巴矢量图标库去下载软件图标

2.去阿里巴巴矢量图标库下载的图标默认为png格式,还得需要用到图片格式转换工具把png格式转换为ico图标格式即可,这里用到的转换工具为万彩办公大师软件操作如下图
