Pyinstaller 和 Pycrypto

5 投票
4 回答
10696 浏览
提问于 2025-04-18 03:51

我们最近在一个项目中添加了pycrypto库,但现在用pyinstaller打包后,软件无法运行。

我之前在使用pyinstaller时遇到过新库的问题,但这次的情况我实在解决不了。

当我尝试运行打包好的软件时,遇到的错误如下(抱歉我只是大概说一下,打包过程比较耗时)

最开始的错误是这样的:

No package Crypto.Cipher

于是我在我的.spec文件中把'Crypto'加到了hiddenimports里。然后我又遇到了:

No module named Cipher

接着我把'Crypto'改成了'Crypto.Cipher',结果又出现了:

Crypto.Cipher has no attribute AES

然后我把'Crypto.Cipher'改成了'Crypto.Cipher.AES',结果又是:

File "C:\Folder\made\by\pyinstaller\Crypto.Cipher.AES", line 49 in <module>
ImportError: cannot import name blockalgo

最后我把'Crypto.Cipher.AES'改成了'Crypto.Cipher.AES.blockalgo',但错误依然没有改变。

我尝试了几种不同的配置,但打包脚本的输出总是显示类似的信息:

ERROR: Hidden import 'blockalgo' not found.

有没有人知道怎么才能正确导入,或者有什么技巧可以让pycrypto和pyinstaller配合得更好?

4 个回答

1

来自 这个链接 : 使用 pycryptodomex 替代 pycryptodome。还有 @galgalesh 在提问下的评论提到,为什么 pycrypto 不应该再使用

pip uninstall -y pycrypto
pip uninstall -y pycryptodome
pip install pycryptodomex

pycryptodomex 提供了一个清晰的 Cryptodome 模块来替代 Crypto。所以,在你的 .py 程序中,把 Crypto 替换成 Cryptodome:

from Cryptodome.PublicKey import RSA

我现在重新运行了 pyinstaller,结果正常。无需做任何特别的 hiddenimports 等等。在 dist 文件夹里,现在有一个清晰的 Crpytodome 文件夹,里面包含所有的 .pyd 文件。

1

改动?为什么不直接添加呢?把这些内容加到 hiddenimport 里就解决了这个问题: 'Crypto', 'Crypto.Cipher', 'Crypto.Cipher.AES', 'Crypto.Random',

3

这个回答:

来自 https://stackoverflow.com/a/48408950/4355695:使用 pycryptodomex 替代 pycryptodome。而 @galgalesh 在提问下的评论解释了为什么不应该再使用 pycrypto。

你可以用以下命令卸载旧的库:

pip uninstall -y pycrypto

pip uninstall -y pycryptodome

然后安装新的库:

pip install pycryptodomex

pycryptodomex 提供了一个清晰的 Cryptodome 模块来替代 Crypto。所以,在你的 .py 程序中,把 Crypto 替换成 Cryptodome:

from Cryptodome.PublicKey import RSA

我现在重新运行了 pyinstaller,结果很好。没有必要做任何特别的隐藏导入等。在 dist 文件夹里,现在有一个清晰的 Cryptodome 文件夹,里面放着所有的 .pyd 文件。

对我来说,运行得非常完美!

使用 pycryptodomex 替代 pycrypto,就能正常工作!

我觉得这是因为 Python 3.6 和 pycrypto 的重大更新导致的!然后它就不再支持 2.7.16 了!

3

根据pyinstaller的手册

你可以通过使用Python的详细导入标志来确认隐藏导入是否是问题所在。如果导入信息显示“找不到模块”,但warnproject.txt文件中没有相同模块的“没有名为...的模块”消息,那么问题就是隐藏导入。

隐藏导入是在分析阶段通过钩住模块(进行隐藏导入的那个模块)来处理的。具体步骤如下:

  1. 创建一个名为hook-module.py的文件(其中module是完整的Python名称,比如hook-xml.dom.py),并把它放在某个地方。记住这个地方,作为你的私有钩子目录。

  2. 在.spec文件中,将你的私有钩子目录作为hookspath参数传递给Analysis,这样就会被搜索到。例如:

    a = Analysis(['myscript.py'], hookspath='/my/priv/hooks') 在大多数情况下,钩子模块只需要一行代码:

    hiddenimports = ['module1', 'module2'] 当Analysis找到这个文件时,它会像显式导入module1和module2一样继续处理。

这个问题似乎相关,答案也可能对你有帮助。

最后,这个报告似乎包含了类似的问题。用户似乎通过更新到pyinstaller 2.1来解决了这个问题,所以如果你还没试过,可以考虑一下。

撰写回答