如何使用 - honefile和-add-data选项与pyinstaller一起编译.exe



我试图将程序编译到.exe中,以在工作中的几台计算机中分发。我需要它是一个文件,因此我在Pyinstaller中使用了 - file选项。好吧,该程序有几个文件取决于它,因此我为每个文件都使用了-ADD-DATA选项,并且似乎可以正常工作。如果我使用-onedir选项对其进行编译,一切都可以很好地工作,但是如果我更改为 - file,那就是它破裂的时候。我遇到了一个错误,说找不到(附加文件(。

我在论坛和Pyinstaller手册上进行了大量研究,并查看了MEI ****文件夹。看来我的其他文件在运行时正确加载到了文件夹中,但是我真的不明白这是有用的,因为.exe只会在其工作目录中查找文件。我尝试使用 - runtime-tmpdir选项指向我可以从中运行.exe的文件夹,但它仍然会创建mei *****文件夹,该文件夹是随机命名的,因此无济于事。这是我在终端中运行的命令。我还尝试更改.spec文件并以此运行Pyinstaller,并且我遇到了完全相同的问题。

pyinstaller.exe ^
--onefile ^
--runtime-tmpdir 
"C:\Users\MyUser\PycharmProjects\helloworld\TempRuntime" ^
--add-data="DI1.npy;." ^
--add-data="DI2.npy;." ^
--add-data="DI3.npy;." ^
--add-data="DI4.npy;." ^
--add-data="DI5.npy;." ^
--add-data="DI6.npy;." ^
--add-data="OwnerPredict2.joblib;." ^
connectToOracle.py

(编辑(,这是代码的一部分,实际上需要这些文件。使用Numpy负载并转换为Pandas DataFrame。

TestFrame.fillna(0, inplace=True)
print('Copying Dataframe')
TestFrameFinal = TestFrame.copy(deep=True)
DI1 = load('DI1.npy', allow_pickle = True).item()
DI2 = load('DI2.npy', allow_pickle = True).item()
DI3 = load('DI3.npy', allow_pickle = True).item()
DI4 = load('DI4.npy', allow_pickle = True).item()
DI5 = load('DI5.npy', allow_pickle = True).item()
DI6 = load('DI6.npy', allow_pickle = True).item()
model = jl('OwnerPredict2.joblib')

我希望能够将所有这些编译成一个.exe,无论大小或慢,它都可以在我的工作中的任何PC上执行。我需要将这些额外的文件解开为.exe可以找到的位置,以便所有内容都可以正常运行。

该解决方案是修改代码,以便使用运行时信息来知道它是从捆绑的.exe还是作为原始Python源运行的,并使用其他文件 - 数据文件的系统路径。

您当前正在尝试从当前工作目录加载数据文件,该目录通常是.exe所属于的目录。但是,数据文件位于您提到的MEI****文件夹中。

供参考,这是来自Pyinstaller文档的相关段落:

当您的程序未冻结时,标准Python变量__file__是现在执行脚本的完整路径。当捆绑应用程序启动时,引导加载程序会设置sys.frozen属性,并将绝对路径存储到sys._MEIPASS中的捆绑文件夹。对于一个折叠捆绑包,无论用户可能将其放置在何处,这都是通往该文件夹的途径。对于单文件捆绑包,这是通往Bootloader创建的_MEIxxxxxx临时文件夹的途径。

作为一个简单的示例,假设您有一个Python脚本app.py,该脚本只需打印出与脚本一起存储的名为data.txt的数据文件的内容。您可以通过在命令行上运行pyinstaller --onefile --add-data="data.txt;." app.py来捆绑它。为了确保Python脚本app.py和捆绑可执行的app.exe都可以找到数据,源代码可以是这样的:

import sys
from pathlib import Path
if getattr(sys, 'frozen', False):
    folder = Path(sys._MEIPASS)
else:
    folder = Path(__file__).parent
file = folder/'data.txt'
data = file.read_text()
print(data)

最新更新