PyInstaller打包FastAPI+Uvicorn服务后弹出空白CMD窗口如何解决?
解决PyInstaller打包Uvicorn/FastAPI应用后弹出CMD窗口的问题
核心原因
Uvicorn默认会启动多进程处理请求,即使主进程通过--noconsole设置为无控制台,子进程仍会创建空白CMD窗口。此外,PyInstaller打包多进程Python应用时需要额外处理,否则会触发控制台窗口创建。
解决方案
方案1:强制Uvicorn单进程运行并添加打包兼容代码
- 在代码开头添加
multiprocessing.freeze_support(),这是PyInstaller打包多进程应用的必备步骤,避免子进程异常创建控制台:
import multiprocessing multiprocessing.freeze_support() # 你的FastAPI和WebSocket代码 from fastapi import FastAPI, WebSocket app = FastAPI() # ... 你的WebSocket端点代码 ...
- 修改Uvicorn启动配置,强制单进程并禁用日志相关的控制台输出:
import uvicorn import threading config = uvicorn.Config( app, host="0.0.0.0", port=exposed_port, access_log=False, reload=False, log_config=None, workers=1, # 强制单进程,避免子进程创建控制台 loop="asyncio" # 使用asyncio事件循环,减少进程创建 ) server = uvicorn.Server(config) server_thread = threading.Thread(target=server.run, daemon=True) server_thread.start()
方案2:调整PyInstaller打包参数
确保打包命令包含以下参数:
pyinstaller --noconsole --onefile --hidden-import uvicorn.workers your_script.py
--noconsole:禁用主进程控制台--onefile:打包为单个EXE文件(可选,但能减少依赖问题)--hidden-import uvicorn.workers:显式导入Uvicorn的工作进程模块,避免打包时遗漏
方案3:Windows平台专属:强制隐藏控制台窗口
如果上述方案仍无效,可以使用Windows API强制隐藏已创建的控制台窗口(需提前安装pywin32库:pip install pywin32):
import win32gui import win32con def hide_console_window(): # 获取当前控制台窗口并隐藏 hwnd = win32gui.GetConsoleWindow() if hwnd: win32gui.ShowWindow(hwnd, win32con.SW_HIDE) # 在启动服务器后调用该函数 server_thread.start() hide_console_window()
验证方法
打包完成后运行EXE文件,确认无CMD窗口弹出,同时通过WebSocket客户端测试服务是否正常运行。
内容的提问来源于stack exchange,提问作者Mateusz Woźniak
相关产品推荐
相关产品推荐

