gma*_*s80 2 dll version dependency-management python-2.7 python-3.x
在 Windows 上,我有一个 Python 库 (*.pyd),我需要检查链接的 Python 版本。它可以是 Python 2.7.x 或 3.x。
当我使用以下命令运行类似的操作时win32api(改编自此处: https: //stackoverflow.com/a/20064736/2741329):
def get_pyd_python_version(pyd_path):
"""
Get the python version required by the passed pyd library
"""
import win32api
print("- pyd path: %s" % str(pyd_path))
try:
info = win32api.GetFileVersionInfo(pyd_path, '\\')
except win32api.error as e:
print(str(e.strerror) + " > " + pyd_path)
return ""
python_version = "%s.%s.%s.%s" % (
str(win32api.HIWORD(info['FileVersionMS'])),
str(win32api.LOWORD(info['FileVersionMS'])),
str(win32api.HIWORD(info['FileVersionLS'])),
str(win32api.LOWORD(info['FileVersionLS'])))
return python_version
Run Code Online (Sandbox Code Playgroud)
我得到:The specified resource type cannot be found in the image file.
与其他“正确”构建的 pyd 库(例如,win32api.pyd)一起使用。
由于 Dependency Walker 与不完整的pyd 一起使用的 Dependency Walker 正确显示了 DLL,我想知道是否有一种方法可以通过编程方式(使用 Python)从这样的事实中获取版本信息。
- - 编辑 - -
基于pefile库和@vyktor的答案,我通过下载这个fork: https: //github.com/BlackXeronic/pefile_py3
并使用这样的方法(也检查架构)来完成这项工作:
from __future__ import absolute_import, print_function
import sys
sys.path.append('./pefile_py3-master')
import pefile
print("python env: v.%s.%s" % (sys.version_info.major, sys.version_info.minor))
print("pefile lib: v.%s" % pefile.__version__)
dll_path = r'C:/Python27/DLLs/bz2.pyd'
print("path to pyd: %s" % dll_path)
pe = pefile.PE(dll_path)
if pe.is_dll():
for entry in pe.DIRECTORY_ENTRY_IMPORT:
if "python" in entry.dll:
if pe.FILE_HEADER.Machine == 0x14C:
arch = "x86"
elif pe.FILE_HEADER.Machine == 0x8664:
arch = "x64"
else:
arch = "unknown"
print(">>> importing %s: v.%s [%s] <<<" % (entry.dll, entry.dll[6:8], arch))
Run Code Online (Sandbox Code Playgroud)
这是我使用 Python 3.4.3 解释器得到的结果:
python env: v.3.4
pefile lib: v.1.2.10-139
path to pyd: C:/Python27/DLLs/bz2.pyd
>>> importing python27.dll: v.27 [x86] <<<
Run Code Online (Sandbox Code Playgroud)
我正在对此进行测试C:\Python32\DLLs\bz2.pyd,但我没有看到任何与 python 相关的详细信息(文件刚刚重命名为.dll):

与 python 版本相关的唯一信息位于 IAT 内部:

因此,您只需解析 PE 文件并查找导入 DLL 名称即可。关于从文件加载 IAT有几个问题,我使用pefile扩展名做到了这一点(由gmas80 在评论中建议):
C:\Python27>python.exe
Python 2.7.2 (default, Jun 12 2011, 15:08:59) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import pefile
>>> p = pefile.PE(r'C:\Python32\DLLs\bz2.pyd')
>>> p.is_dll()
True
>>> for entry in p.DIRECTORY_ENTRY_IMPORT:
... print entry.dll
...
python32.dll
MSVCR90.dll
KERNEL32.dll
>>> p = pefile.PE(r'C:\Python27\DLLs\bz2.pyd')
>>> p.is_dll()
True
>>> for entry in p.DIRECTORY_ENTRY_IMPORT:
... print entry.dll
...
python27.dll
MSVCR90.dll
KERNEL32.dll
Run Code Online (Sandbox Code Playgroud)
您只需编写一个查找pythonXX.dll字符串的检查即可。
不幸的是,这仅适用于 python 2.7(也许有人可以找到 pefile 的 3.2 分支)。
据我所知,WinAPI 本身不提供在文件内查找导入的简单方法,因此使用嵌入所有结构的第 3 方扩展是执行此操作的最佳方法。
| 归档时间: |
|
| 查看次数: |
3544 次 |
| 最近记录: |