【问题标题】:Pyinstaller & PycryptoPyinstaller 和 Pycrypto
【发布时间】:2014-04-23 01:27:06
【问题描述】:

我们最近将 pycrypto 添加到我们一直在处理的项目中,现在我无法在使用 pyinstaller 构建该软件后运行该软件。

我在 pyinstaller 中遇到了新软件包的问题,​​但我无法特别解决这个问题。

我在尝试运行构建的软件时遇到的错误如下(抱歉解释,构建需要相当长的时间)

一开始是这样的:

No package Crypto.Cipher

所以我将'Crypto' 添加到我的.spec 文件中的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 配合使用?

【问题讨论】:

  • Pycrypto 是unmaintained and has known vulnerabilities。使用pycryptodome,它是一个替代品。
  • 我尝试安装 pycryptodome。因为缺少OSError: Cannot load native module 'Crypto.Hash._MD5' 而出错。我将它包含在 hiddenimports 中.. 它在构建中创建了一个Crypto.Hash._MD5.pyd 文件,但仍然没有骰子.. 程序崩溃。而且看起来它在所有错误的地方寻找。
  • 看到了一个使用 pycryptodomex 代替的记录:stackoverflow.com/a/48408950/4355695

标签: python pyinstaller pycrypto


【解决方案1】:

根据the pyinstaller manual

您可以使用 Python 的详细导入标志来验证隐藏导入是否存在问题。如果导入消息显示“未找到模块”,但 warnproject.txt 文件中没有同一模块的“没有名为...的模块”消息,则问题是隐藏导入。

隐藏导入是通过在分析时挂钩模块(执行隐藏导入的模块)来处理的。请按以下方式进行操作:

  1. 创建一个名为 hook-module.py 的文件(其中 module 是完全限定的 Python 名称,例如 hook-xml.dom.py)并将其放置在某处。记住这个地方作为你的私有 hooks 目录。

  2. 在 .spec 文件中,将您的私有 hooks 目录作为 hookspath 参数传递给 Analysis,以便搜索。示例:

    a = 分析(['myscript.py'], hookspath='/my/priv/hooks') 在大多数情况下,钩子模块只有一行:

    hiddenimports = ['module1', 'module2'] 当 Analysis 找到这个文件时,它将像模块显式导入 module1 和 module2 一样继续进行。

This question 似乎相关,答案可能对您也有用。

最后,this report 似乎包含类似的问题。用户似乎可以通过更新到 pyinstaller 2.1 来修复它,所以如果您还没有尝试过,您可能想尝试一下。

【讨论】:

    【解决方案2】:

    这个答案:

    来自https://stackoverflow.com/a/48408950/4355695:使用 pycryptodomex 而不是 pycryptodome。 @galgalesh 在 OP 问题下方的评论给出了为什么不应再使用 pycrypto。

    pip 卸载 -y pycrypto pip 卸载 -y pycryptodome pip install pycryptodomex

    pycryptodomex 提供了一个明确明确的 Cryptodome 模块来替换 Crypto。因此,在您的 .py 程序中,将 Crypto 替换为 Cryptodome:

    从 Cryptodome.PublicKey 导入 RSA

    我现在重新运行了 pyinstaller,它运行正常。无需进行任何特殊的隐藏导入等操作。在 dist 文件夹中,现在有一个清晰的 Crpytodome 文件夹,其中包含所有 .pyd 文件。

    非常适合我!

    使用 pycryptodomex 代替 pycrypto 就可以了!

    我认为这是由于 python 3.6 和 pycrypto 的主要演变可以使用!然后它停止使用 2.7.16 !

    【讨论】:

    • 我找到了更好的解决方案,你可以下载这个版本:pycrypto-2.6.win32-py2.7.exe!然后进行编译,使用 pyinstaller 上面的 UPX packer 编译成功!
    【解决方案3】:

    改变?为什么不加?将这些添加到hiddenimport 解决了这个问题:'Crypto', 'Crypto.Cipher', 'Crypto.Cipher.AES', 'Crypto.Random',

    【讨论】:

    • 必须有比明确包括所有子模块更好的方法来解决这个问题。
    【解决方案4】:

    来自https://stackoverflow.com/a/48408950/4355695:使用pycryptodomex 而不是pycryptodome。 @galgalesh 在 OP 问题下方的评论给出了为什么 pycrypto should no longer to be used

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

    pycryptodomex 提供了一个明确明确的 Cryptodome 模块来替换 Crypto。因此,在您的 .py 程序中,将 Crypto 替换为 Cryptodome:

    from Cryptodome.PublicKey import RSA
    

    我现在重新运行了 pyinstaller,它运行正常。无需进行任何特殊的隐藏导入等操作。在 dist 文件夹中,现在有一个清晰的 Crpytodome 文件夹,其中包含所有 .pyd 文件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-09
      • 2014-03-28
      • 2015-05-20
      相关资源
      最近更新 更多