在64位Windows上获取并安装crypto.dll的位置

问题描述 投票:14回答:3

注意:这不是Visual Studio的问题,而是与不兼容的dll版本有关。以下步骤复制问题,因为在调试模式下在Visual Studio中运行会因抛出异常而中断。如果你只是运行,抛出的异常在别处处理,程序运行正常。但由于我花了很多时间在调试模式,我宁愿解决这个问题。

调试时,我希望能够进入我在Visual Studio中添加到虚拟环境的模块。我收到一个“找不到库”的错误,我无法修复。以下是步骤:

  1. 在Visual Studio中创建一个新的Python应用程序。
  2. 为该应用程序创建虚拟环境(Python 3.6 64位)。
  3. pip install twilio进入你的虚拟环境。您将获得以下输出。

...

   ----- Installing 'twilio' -----
Collecting twilio
  Using cached twilio-6.10.5-py2.py3-none-any.whl
Collecting pytz (from twilio)
  Using cached pytz-2018.3-py2.py3-none-any.whl
Collecting six (from twilio)
  Using cached six-1.11.0-py2.py3-none-any.whl
Collecting PyJWT>=1.4.2 (from twilio)
  Using cached PyJWT-1.6.0-py2.py3-none-any.whl
Collecting requests>=2.0.0; python_version >= "3.0" (from twilio)
  Using cached requests-2.18.4-py2.py3-none-any.whl
Collecting pysocks; python_version >= "3.0" (from twilio)
  Using cached PySocks-1.6.8.tar.gz
Collecting certifi>=2017.4.17 (from requests>=2.0.0; python_version >= "3.0"->twilio)
  Using cached certifi-2018.1.18-py2.py3-none-any.whl
Collecting chardet<3.1.0,>=3.0.2 (from requests>=2.0.0; python_version >= "3.0"->twilio)
  Using cached chardet-3.0.4-py2.py3-none-any.whl
Collecting urllib3<1.23,>=1.21.1 (from requests>=2.0.0; python_version >= "3.0"->twilio)
  Using cached urllib3-1.22-py2.py3-none-any.whl
Collecting idna<2.7,>=2.5 (from requests>=2.0.0; python_version >= "3.0"->twilio)
  Using cached idna-2.6-py2.py3-none-any.whl
Installing collected packages: pytz, six, PyJWT, certifi, chardet, urllib3, idna, requests, pysocks, twilio
  Running setup.py install for pysocks: started
    Running setup.py install for pysocks: finished with status 'done'
Successfully installed PyJWT-1.6.0 certifi-2018.1.18 chardet-3.0.4 idna-2.6 pysocks-1.6.8 pytz-2018.3 requests-2.18.4 six-1.11.0 twilio-6.10.5 urllib3-1.22
----- Successfully installed 'twilio' -----
  1. 将以下行添加到.py文件的顶部: from twilio.rest import Client
  2. 在Visual Studio中,转到工具>选项> python>调试。确保选中“启用Python标准库的调试”
  3. 运行该应用程序。您收到以下错误:

ModuleNotFoundError:没有名为'OpenSSL'的模块

  1. pip install pyopenssl你得到以下输出:

...

----- Installing 'pyopenssl' -----
Collecting pyopenssl
  Using cached pyOpenSSL-17.5.0-py2.py3-none-any.whl
Requirement already satisfied: six>=1.5.2 in c:\users\x\source\repos\pythonapplication9\pythonapplication9\env\lib\site-packages (from pyopenssl)
Collecting cryptography>=2.1.4 (from pyopenssl)
  Using cached cryptography-2.1.4-cp36-cp36m-win_amd64.whl
Requirement already satisfied: idna>=2.1 in c:\users\x\source\repos\pythonapplication9\pythonapplication9\env\lib\site-packages (from cryptography>=2.1.4->pyopenssl)
Collecting cffi>=1.7; platform_python_implementation != "PyPy" (from cryptography>=2.1.4->pyopenssl)
  Using cached cffi-1.11.5-cp36-cp36m-win_amd64.whl
Collecting asn1crypto>=0.21.0 (from cryptography>=2.1.4->pyopenssl)
  Using cached asn1crypto-0.24.0-py2.py3-none-any.whl
Collecting pycparser (from cffi>=1.7; platform_python_implementation != "PyPy"->cryptography>=2.1.4->pyopenssl)
  Using cached pycparser-2.18.tar.gz
Installing collected packages: pycparser, cffi, asn1crypto, cryptography, pyopenssl
  Running setup.py install for pycparser: started
    Running setup.py install for pycparser: finished with status 'done'
Successfully installed asn1crypto-0.24.0 cffi-1.11.5 cryptography-2.1.4 pycparser-2.18 pyopenssl-17.5.0
----- Successfully installed 'pyopenssl' -----
  1. 运行该应用程序。您收到以下错误: asn1crypto._ffi.LibraryNotFoundError: The library libcrypto could not be found

错误在_big_num_ctypes.py中名为asn1crypto的文件中抛出。抛出它的代码行是:

libcrypto_path = find_library(b'crypto' if sys.version_info < (3,) else 'crypto')
if not libcrypto_path:
    raise LibraryNotFoundError('The library libcrypto could not be found')

更新:我被要求提供完整的回溯。我用这种方式修改代码来打印它:

import unittest
import traceback

class Test_test1(unittest.TestCase):
    def test_A(self):
        try:
            from twilio.rest import Client
        except Exception as e:
            print('foo')
            foo = traceback.extract_stack()
            traceback.print_exc(e)

if __name__ == '__main__':
    unittest.main()

和导入行一样抛出异常,但是没有捕获异常,并且'except'子句中的行永远不会从twilio.rest import客户端执行

更新2:我以某种方式在@Prateek和@ user8212173之后开始工作。但现在它不再起作用了。正如两者所建议的那样,问题是crypto.dll不存在。所以我通过以下步骤添加它没有成功:

  1. 我从https://slproweb.com/products/Win32OpenSSL.html安装了Win64 OpenSSL v1.1.0j(从https://wiki.openssl.org/index.php/Binaries指向)。它不包含crypto.dll。
  2. 然后我从http://www.dlldownloader.com/crypto-dll/安装了crypto.dll(如@ user8212173建议)(只有32位版本)并按照说明操作。然后我收到一条新的错误消息“ImportError:DLL加载失败:%1不是一个有效的Win32应用程序”这意味着我安装的crypto.dll存在版本冲突(我在64位计算机上运行64位python)。我记得从Unofficial Windows Binaries for Python Extension Packages安装它我找不到它。那么我在哪里可以获得64位版本的crypto.dll?
python python-3.x dll openssl python-import
3个回答
5
投票

我搜索了很多,发现你缺少crypto.dll文件。您的代码正在查找此dll文件,但无法找到它。

请注意这不会被pip install crypto安装,因为这是python库,代码正在寻找一个dll文件。

ctypes.util.find_library从windows环境路径变量中搜索dll文件。

Reference : find_library() in ctypes

验证我检查了。

find_library('l2gpstore')
>>'C:\\WINDOWS\\system32\\l2gpstore.dll'
find_library('java')
>>'C:\\Program Files\\Java\\jdk-9.0.4\\bin\\java.dll'

此外,你应该从这里安装OpenSSLlibcrypto模块

OpenSSL

OpenSSL安装instructions

主源维护在我们的git存储库中,该存储库可通过网络访问并克隆在https://github.com/openssl/openssl的GitHub上。错误和拉取补丁(问题和拉取请求)应该是GitHub仓库中的文件。请熟悉许可证。

关于OpenSSL的libcrypto

reference : GitHub

libcrypto(具有特定于平台的命名):提供SSL / TLS所需的一般加密和X.509支持,但逻辑上不是它的一部分。

一旦安装了二进制文件并检查环境变量中的一个路径字符串中是否有crypto.dll,就应该解决此问题。

如果没有将它添加到路径变量并检查。

Update:

更新问题已更新,问题再次出现。

与1.0.2相比,OpenSSL 1.1.0存在架构方面的变化

2018年9月13日 - OpenSSL 1.1.0及更高版本与以前的版本完全不同。用户应安装1.0.2系列(LTS)和1.1.1(LTS)系列,以实现最大的应用兼容性。开发人员需要重新编译他们的软件才能支持1.1.1。有关更多详细信息,请参阅官方OpenSSL发布策略文档。 - 昨天Prateek

如果您从Github打开1.0.2,您可以看到crypto.h文件,最新版本中缺少相同的文件。 OpenSSL也有DLL名称的变化,他们renamed libeay32 to libcrypto

您需要发布在帖子中使用asn1crypto库的代码。没有代码在您的帖子中明确使用asn1crypto。因此,无法使用pipenv重现您的问题。

确保您也使用更新的库。

我不建议从DLLdownloader等不可靠的源代码下载DLL源代码


如果你遇到最新版本的OpenSSLasn1crypto的问题,最好将OpenSSL降级到1.0.2,我认为考虑到它随crypto.h文件一起发布会有效。

祝好运!


3
投票

我试图在我的计算机上重现错误,并且当我运行“错误生成”文件_big_num_ctypes.py时成功。虽然,我没有Visual Studio,但错误源于缺少crypto.dll文件。我们将逐步推断这一点。让我们首先检查文件_big_num_ctypes.py中导致代码片段的错误:

#imports
from ctypes.util import find_library
.
.
from .._ffi import LibraryNotFoundError, FFIEngineError

try:
# On Python 2, the unicode string here may raise a UnicodeDecodeError as it
# tries to join a bytestring path to the unicode name "crypto"
    libcrypto_path = find_library(b'crypto' if sys.version_info < (3,) else 'crypto')
    if not libcrypto_path:
        raise LibraryNotFoundError('The library libcrypto could not be found')
.
.
except (AttributeError):
    raise FFIEngineError('Error initializing ctypes')

我跑了文件:

C:\>cd "C:\ProgramData\Anaconda3\Lib\site-packages\asn1crypto\_perf"
C:\ProgramData\Anaconda3\Lib\site-packages\asn1crypto\_perf>python _big_num_ctypes.py

并为库导入有一个Traceback

Traceback (most recent call last):
  File "_big_num_ctypes.py", line 27, in <module>
    from .._ffi import LibraryNotFoundError, FFIEngineError
ValueError: attempted relative import beyond top-level package

所以,我更改了.ffito的导入路径:

from asn1crypto._ffi import LibraryNotFoundError, FFIEngineError

在第二次运行时,出现了缺少的libcrypto库错误:

asn1crypto._ffi.LibraryNotFoundError: The library libcrypto could not be found

在C:\ Windows \ System32和/或SYSWOW64(对于64位)找不到名为crypto的dll库时引发异常

libcrypto_path = find_library(b'crypto' if sys.version_info < (3,) else 'crypto')

find_library的目的是找到一个指定的库并返回一个路径名。如docs中所述,此方法的行为随OS而变化。如果此方法找不到任何包,则返回None

>>> from ctypes.util import find_library
>>> print(find_library("c"))
None

在我们的例子中,搜索是crypto.dll,我在我的电脑上找不到这个文件。所以,我完全按照here的说明下载并安装了它。当我再次检查时:

 >>> find_library('crypto')
'C:\\windows\\system32\\crypto.dll'

现在我再次运行python _big_num_ctypes.py并获得了不同的Traceback

    Traceback (most recent call last):
  File "_big_num_ctypes.py", line 37, in <module>
    libcrypto = CDLL(libcrypto_path)
  File "C:\ProgramData\Anaconda3\lib\ctypes\__init__.py", line 348, in __init__
    self._handle = _dlopen(self._name, mode)
OSError: [WinError 193] %1 is not a valid Win32 application

对上述错误的进一步调查显示,如果我使用64位Python的32位DLL,反之亦然,那么我可能会遇到here所解释的错误。所以,我安装了Python 3.6 32位并再次尝试使用py -3.6-32 _big_num_ctypes.py。我还安装了所有必需的软件包,但是这个错误仍然存​​在。

我们可能需要为Crypto包提供32位二进制文​​件吗?这个answerthis提供了更多信息。

我意识到Pycryptodome是一个定期维护的包,比旧的Crypto包更受欢迎,但仍然可以安装在Crypto下。另一点需要注意的是,此软件包的要求之一是MS Visual Studio 2015(Community Edition)和C / C ++编译器以及仅可再发行组件。目前可能缺少某些C ++编译器文件或MS Visual Studio文件并导致这些问题发生。

如果你安装了上述所有先决条件,crypto.dll文件和Pycryptodomepackage,我相信这个错误将被解决。您已经安装了其他必需的软件包OpenSSLTwilio。不幸的是,我被限制在我的计算机上安装MS Visual Studio,所以我无法进一步测试。

我还运行了unittest代码,它为我成功运行:

#Output

.
----------------------------------------------------------------------
Ran 1 test in 0.771s

OK

0
投票

这是我的Windows 10解决方案,2017年视觉工作室社区,

打开文件C:\ Program Files(x86)\ Microsoft Visual Studio \ Shared \ Python36_64 \ Lib \ site-packages \ asn1crypto_perf_big_num_ctypes.py然后更改代码:

libcrypto_path = find_library(b'crypto' if sys.version_info < (3,) else 'crypto')

至:

libcrypto_path = find_library(b'crypto' if sys.version_info < (3,) else 'libcrypto')

然后错误消息消失了。

libcrypto.dll已经在文件夹C:\ Windows \ System32 \下

© www.soinside.com 2019 - 2024. All rights reserved.