Python脚本转exe遇OSError: [WinError 6]无效句柄错误求助
问题原因与解决方案
原因分析
- WinError 6 直接诱因:你在打包后强制通过
sys.stdin = open(0)重定向标准输入流,当双击运行exe而非在命令行启动时,系统未正确绑定stdin句柄,导致句柄无效报错。 - CSV文件路径缺失:当前代码未处理打包后资源文件的路径问题,PyInstaller默认不会自动将csv文件打包进exe,后续即使解决stdin问题,也会出现文件找不到的错误。
- ChatGPT方案失效原因:
PyInstaller.utils.cli/inputhook属于非公开或版本兼容差的模块,重定向stdin的方式未考虑双击exe时的无控制台上下文,因此无法解决问题。
解决方案
不需要重新编写程序,只需针对输入流、资源文件路径两个核心问题修复即可:
1. 修复标准输入流问题
删除手动修改stdin的代码,确保打包时保留控制台窗口(PyInstaller默认启用,不要加--windowed/--noconsole参数),让系统自动管理stdin流:
if __name__ == "__main__": # 移除sys.stdin = open(0),直接调用main main()
2. 正确打包并读取CSV文件
打包时通过--add-data参数将csv文件包含进exe,同时修改代码获取正确的资源路径:
打包命令(Windows)
pyinstaller --onefile --add-data "*.csv;." main.py
(macOS/Linux将;替换为:)
修改文件读取函数
import csv import sys import os def read_ingredients(file_name): ingredients = [] # 判断是否为打包后的exe环境,获取资源路径 if getattr(sys, 'frozen', False): base_path = sys._MEIPASS # PyInstaller打包后的临时资源目录 else: base_path = os.path.dirname(os.path.abspath(__file__)) # 开发环境路径 file_path = os.path.join(base_path, file_name) with open(file_path, newline='') as csvfile: reader = csv.reader(csvfile) for row in reader: ingredients.append(row[0]) return ingredients # 其余函数保持不变...
3. 输入处理健壮性优化(可选)
添加异常捕获,避免用户输入无效内容导致崩溃:
def main(): dinners = [ "Spaghetti Bolognese", "Nasi Goreng", "Honey and Mustard Chicken Thighs", "Honey and Garlic Chicken Thighs", "Chocolate and Peanut Butter Overnight Oats", "Chickpea and Veg Soup", "Carbonara", "Beef Broccoli and Rice", "Banana Bread" ] print("Please pick which dinners you will have this week:") for index, dinner in enumerate(dinners, start=1): print(f"{index}. {dinner}") # 循环获取有效输入 while True: try: selected_indices = input("Enter the numbers corresponding to your selected dinners separated by spaces: ").split() # 验证输入是否为有效数字且在范围内 selected_dinners = [] for index in selected_indices: idx = int(index) if 1 <= idx <= len(dinners): selected_dinners.append(dinners[idx-1]) else: raise ValueError(f"数字 {idx} 不在可选范围内") break except ValueError as e: print(f"输入错误:{e},请重新输入。") input("Press Enter to generate the shopping list...") shopping_list = generate_shopping_list(selected_dinners) print("\nShopping List:") for ingredient in shopping_list: print(ingredient)
内容的提问来源于stack exchange,提问作者Anne Holmes
相关产品推荐
相关产品推荐

