PyInstaller有时无法正确导入pycrypto

2 投票
3 回答
3986 浏览
提问于 2025-04-18 04:12

我在不同的Ubuntu机器上用PyInstaller打包一个项目。在某些机器上,当我运行生成的项目时,出现了这个错误:

文件 "~/PyInstaller-2.1/proj/build/proj/out00-PYZ.pyz/Crypto.Random", 第28行,出现ImportError: 无法导入名称OSRNG

不过在Python控制台中导入是完全正常的,而且我可以在不打包的情况下顺利执行这个项目。

我尝试过卸载并重新安装pycrypto,但没有成功。我还尝试在主文件中添加一行特定的代码:

from Crypto.Random import OSRNG

这样做是为了让PyInstaller能够识别到它。

3 个回答

0

我通过把 pycrypto / pycryptodome 替换成 pycryptodomex 让它正常工作了。这里分享一个已经发布的答案链接: https://stackoverflow.com/a/50009769/4355695

3

我用hithwen的方案解决了这个问题,不过我用的.spec文件稍微有点不同。我把它放在这里,供大家参考。

# -*- mode: python -*-

#Tweaks to properly import pyCrypto

#Get the path
def get_crypto_path():
    '''Auto import sometimes fails on linux'''
    import Crypto
    crypto_path = Crypto.__path__[0]
    return crypto_path

#Analysis remains untouched
a = Analysis(['myapp.py'],
             pathex=[],
             hiddenimports=[],
             hookspath=None,
             runtime_hooks=None)
#Add to the tree the pyCrypto folder
dict_tree = Tree(get_crypto_path(), prefix='Crypto', excludes=["*.pyc"])
a.datas += dict_tree
#As we have the so/pyd in the pyCrypto folder, we don't need them anymore, so we take them out from the executable path
a.binaries = filter(lambda x: 'Crypto' not in x[0], a.binaries)
#PYZ remains untouched
pyz = PYZ(a.pure)
#EXE remains untouched
exe = EXE(pyz,
          a.scripts,
          exclude_binaries=True,
          name='myapp',
          debug=False,
          strip=None,
          upx=True,
          console=True )
#COLLECT remains untouched
coll = COLLECT(exe,
               a.binaries,
               a.zipfiles,
               a.datas,
               strip=None,
               upx=True,
               name='myapp')
1

我通过在规格文件中添加Crypto目录结构来解决这个问题。

我用这个函数获取路径:

def get_crypto_path():
    '''Auto import sometimes fails on linux'''
    import Crypto
    crypto_path = Crypto.__path__[0]
    return crypto_path

然后在规格文件中替换成这个路径:

dict_tree = Tree('CRYPTO_PATH', prefix='Crypto', excludes=["*.pyc"])
a.datas += dict_tree

撰写回答