Pyinstaller - 编译应用程序后找不到libmagic
Pyinstaller - libmagic not found after compiling app
问题
我正在 Python 中编写应用程序。它在我的 python 环境中工作得很好,但是当我用 PyInstaller 编译它并尝试 运行 生成的可执行文件时,我收到以下错误:ImportError: failed to find libmagic. Check your installation
我感觉这与 "python-magic-bin" 有关,安装包含名为 "magic" 的模块所需的二进制文件,因为如果我卸载 "python-magic-bin"我的 Python 环境并尝试 运行 应用程序,我得到了完全相同的错误。我认为出于某种原因,这些二进制文件没有被携带到编译的 exe 中。
如果有所不同,我从 .whl 文件安装了 "python-magic-bin"。此安装在安装 "magic" 的目录中添加了一个名为 "libmagic" 文件 libmagic.dll 和 magic.mgc 的文件夹。
问题
如果我对这个问题的看法是正确的,我如何让 PyInstaller 携带 "magic" 需要的二进制文件?
重现问题
可以执行以下操作来重现问题:
将此代码复制并粘贴到您的编辑器中。将其保存为名为
"test.py"
import magic
m=magic.MAGIC_NONE
print(m)
从此link下载"python_magic_bin-0.4.14-py2.py3-none-win32.whl"并在解释器中使用以下命令将所需的库安装到Python 3.6
>>> pip install pyinstaller
>>> pip install python-magic
>>> pip install python_magic_bin-0.4.14-py2.py3-none-win32.whl
>>> pip install libmagic
在与 "test.py" 文件相同的目录中打开命令提示符,然后使用以下命令使用 pyinstaller 编译程序:
> pyinstaller test.py
完成后,移动到新创建的 /dist/test 目录 (cd ./dist/test
) 和 运行 .exe 使用:
> ./test.exe
在 运行 之后,您应该会看到一条错误消息:ImportError: failed to find libmagic. Check your installation
和 Failed to execute script test
规格文件
这是我用来编译项目的规范文件。
# -*- mode: python -*-
block_cipher = None
a = Analysis(['main.py'],
pathex=['D:\Home_Python\pytags'],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
exclude_binaries=True,
name='main',
debug=False,
strip=False,
upx=True,
console=True )
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
name='main')
版本
对于这个项目,我使用的是:
- Python 3.6.3
- PyInstaller 3.3.1
- Libmagic 1.0
- Python-魔法0.4.15
- Python-Magic-Bin 0.4.14
几天后我解决了这个问题,所以我将在这里记录我的解决方案,以供将来可能遇到相同问题的任何人使用。
问题在于 libmagic
用于查找正常工作所需的 .dll 文件的方法。
前往 Python 安装下的 Lib/site-packages/magic
,将名为 magic.py
的文件和名为 libmagic
的文件夹复制到 Python 的目录中项目。之后,在您喜欢的 IDE 中打开 magic.py
。如果转到第 156 行,您会看到这段代码:
bin_dist_path = os.path.join(os.path.dirname(__file__), 'libmagic')
这是导致我们出现问题的行。它会在与 magic.py
文件相同的目录中查找名为 libmagic 的文件夹。具体来说,这里的问题是当文件被冻结到 .exe 文件中时,__file__
变量无法正常工作,因此我将 __file__
替换为 sys.executable
。结果行如下所示:
bin_dist_path = os.path.join(os.path.dirname(sys.executable), 'libmagic')
保存文件,编译程序,然后将 libmagic
文件夹复制到与生成的 .exe 文件相同的目录中。
如果您 运行 .exe,现在应该一切正常。
如果有什么我可以澄清的,或者您有任何疑问,请随时提问。
不想把它放在另一个评论中,因为它不会那么明显...
这对我有用。只需更改 .spec 文件以包含额外的文件:
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
extra_files = [('venv/Lib/site-packages/magic','magic')]
a = Analysis(['main.py'],
pathex=['D:\Home_Python\pytags'],
binaries=[],
datas=extra_files,
hiddenimports=[],
...
问题
我正在 Python 中编写应用程序。它在我的 python 环境中工作得很好,但是当我用 PyInstaller 编译它并尝试 运行 生成的可执行文件时,我收到以下错误:ImportError: failed to find libmagic. Check your installation
我感觉这与 "python-magic-bin" 有关,安装包含名为 "magic" 的模块所需的二进制文件,因为如果我卸载 "python-magic-bin"我的 Python 环境并尝试 运行 应用程序,我得到了完全相同的错误。我认为出于某种原因,这些二进制文件没有被携带到编译的 exe 中。
如果有所不同,我从 .whl 文件安装了 "python-magic-bin"。此安装在安装 "magic" 的目录中添加了一个名为 "libmagic" 文件 libmagic.dll 和 magic.mgc 的文件夹。
问题
如果我对这个问题的看法是正确的,我如何让 PyInstaller 携带 "magic" 需要的二进制文件?
重现问题
可以执行以下操作来重现问题:
将此代码复制并粘贴到您的编辑器中。将其保存为名为 "test.py"
import magic m=magic.MAGIC_NONE print(m)
从此link下载"python_magic_bin-0.4.14-py2.py3-none-win32.whl"并在解释器中使用以下命令将所需的库安装到Python 3.6
>>> pip install pyinstaller >>> pip install python-magic >>> pip install python_magic_bin-0.4.14-py2.py3-none-win32.whl >>> pip install libmagic
在与 "test.py" 文件相同的目录中打开命令提示符,然后使用以下命令使用 pyinstaller 编译程序:
> pyinstaller test.py
完成后,移动到新创建的 /dist/test 目录 (
cd ./dist/test
) 和 运行 .exe 使用:> ./test.exe
在 运行 之后,您应该会看到一条错误消息:ImportError: failed to find libmagic. Check your installation
和 Failed to execute script test
规格文件
这是我用来编译项目的规范文件。
# -*- mode: python -*-
block_cipher = None
a = Analysis(['main.py'],
pathex=['D:\Home_Python\pytags'],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
exclude_binaries=True,
name='main',
debug=False,
strip=False,
upx=True,
console=True )
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
name='main')
版本
对于这个项目,我使用的是:
- Python 3.6.3
- PyInstaller 3.3.1
- Libmagic 1.0
- Python-魔法0.4.15
- Python-Magic-Bin 0.4.14
几天后我解决了这个问题,所以我将在这里记录我的解决方案,以供将来可能遇到相同问题的任何人使用。
问题在于 libmagic
用于查找正常工作所需的 .dll 文件的方法。
前往 Python 安装下的 Lib/site-packages/magic
,将名为 magic.py
的文件和名为 libmagic
的文件夹复制到 Python 的目录中项目。之后,在您喜欢的 IDE 中打开 magic.py
。如果转到第 156 行,您会看到这段代码:
bin_dist_path = os.path.join(os.path.dirname(__file__), 'libmagic')
这是导致我们出现问题的行。它会在与 magic.py
文件相同的目录中查找名为 libmagic 的文件夹。具体来说,这里的问题是当文件被冻结到 .exe 文件中时,__file__
变量无法正常工作,因此我将 __file__
替换为 sys.executable
。结果行如下所示:
bin_dist_path = os.path.join(os.path.dirname(sys.executable), 'libmagic')
保存文件,编译程序,然后将 libmagic
文件夹复制到与生成的 .exe 文件相同的目录中。
如果您 运行 .exe,现在应该一切正常。
如果有什么我可以澄清的,或者您有任何疑问,请随时提问。
不想把它放在另一个评论中,因为它不会那么明显...
这对我有用。只需更改 .spec 文件以包含额外的文件:
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
extra_files = [('venv/Lib/site-packages/magic','magic')]
a = Analysis(['main.py'],
pathex=['D:\Home_Python\pytags'],
binaries=[],
datas=extra_files,
hiddenimports=[],
...