返回

Pyinstaller编译python项目为exe遇到的问题,flask服务无法启动

Pyinstaller编译python项目的时候无法启动flask服务

SocketIO(app)无法启动,提示ValueError: Invalid async_mode specified

需要安装以下包: gevent gevent-websocket 然后SocketIO不需要设置async_mode,并且使用pyinstaller的时候需要设置--hidden-import

--hidden-import 是 PyInstaller 打包工具的一个命令行选项,它用于指定程序运行时可能会动态导入的模块,但是这些模块在静态分析时可能没有被检测到。使用 --hidden-import 选项可以确保这些模块被包含在最终打包的可执行文件中。

有些文件夹或文件在exe运行时的临时运行路径中没有

为什么我会发现这个,因为pyinstall打包的时候不添加 -w 参数可以显示出一个cmd窗口,可以查看运行的状态 回到上面的问题,这是因为有时候pyinstaller可能并不会将你项目下所有的文件夹都包含到临时运行路径中;这个时候就需要使用pyinstaller的--add-data

--add-data 是 PyInstaller 的一个命令行选项,它用于将非代码文件添加到打包的应用程序中。这些文件可以是图像、数据表、证书文件等等,任何程序在运行时需要的额外资源。在打包应用程序时,PyInstaller 不会自动包含这些资源文件,所以 --add-data 用来显式指定它们。

使用方法: pyinstaller --add-data '<源路径>;<目标路径>' your_script.py 源路径就是你的项目下的文件夹,一般相对当前项目;目标路径就是运行时候的路径位置,目标路径一般是和源路径一样,也可以是.,.就是代表临时运行路径下

虽然--add-data添加了,还是无法访问文件

这个时候需要处理下需要访问的文件的目录: python # 检查是否处于打包环境 if getattr(sys, 'frozen', False): # 如果是,使用 sys._MEIPASS base_path = sys._MEIPASS else: # 否则使用当前文件的目录 base_path = os.path.dirname(__file__) sys._MEIPASS是程序运行时候创建的临时目录,程序需要的python包以及--add-data添加的东西都会在里面,一般是c盘的临时文件夹中,具体位置可以自己print看看

socketio.run或app.run不行?

或者直接添加allowunsafewerkzeug=True这个参数,如果不介意它的红色提示的话

完整的pyinstall命令

python pyinstaller --onefile --hidden-import=gevent --hidden-import=gevent-websocket --hidden-import=gevent.ssl --hidden-import=gevent.builtins --hidden-import=threading --hidden-import=engineio.async_drivers.threading --add-data "templates;templates" --add-data "log.txt;." services.py 要正常运行SocketIO(app),gevent,gevent-websocket,gevent.ssl,gevent.builtins,threading,engineio.async_drivers.threading缺一不可 确保是在项目虚拟环境中使用pyinstaller,且pyinstaller也是在虚拟环境中安装

评论