有人知道如何查找已传递给我的函数的二进制文件的版本号吗?
我从这个页面获取了以下代码:
def version(fpath):
f = open(fpath, 'rb')
s = f.read(1024)
print s
f.close()
然而,这并没有给我提供类似于上述网站显示的有用输出。
编辑: @BoazYaniv 告诉我,文件格式在这个问题中起着重要作用。这是一个Windows可执行文件。
有人知道如何查找已传递给我的函数的二进制文件的版本号吗?
我从这个页面获取了以下代码:
def version(fpath):
f = open(fpath, 'rb')
s = f.read(1024)
print s
f.close()
然而,这并没有给我提供类似于上述网站显示的有用输出。
编辑: @BoazYaniv 告诉我,文件格式在这个问题中起着重要作用。这是一个Windows可执行文件。
您可以使用一个现成的模块来解析EXE文件:http://code.google.com/p/pefile/
您可以使用以下代码读取它:
import pefile
pe = pefile.PE(r'C:\Windows\notepad.exe')
FileVersion = pe.FileInfo[0].StringTable[0].entries['FileVersion']
ProductVersion = pe.FileInfo[0].StringTable[0].entries['ProductVersion']
正如您所看到的,Windows EXE(和DLL)文件存储两种不同类型的版本,即FileVersion和ProductVersion。很多时候它们是相同的,但有时它们可能不同 - 这完全取决于制作EXE的人。
为了使事情更加复杂,这些PE字符串表中的两个字符串并不是Windows编译器保存版本的唯一位置。在EXE中还有另外两个FileVersion和ProductVersion值,只是它们以32位整数对的形式存储,每个整数再分别分成两个16位整数(在Windows API术语中称为WORDs)。总体上,每个版本值(FileVersion和ProductVersion)都有4个16位的WORDs,表示版本号的点分隔部分。您也可以使用pefile获取它们:
pe = pefile.PE(r'C:\Windows\notepad.exe')
FileVersionLS = pe.VS_FIXEDFILEINFO.FileVersionLS
FileVersionMS = pe.VS_FIXEDFILEINFO.FileVersionMS
ProductVersionLS = pe.VS_FIXEDFILEINFO.ProductVersionLS
ProductVersionMS = pe.VS_FIXEDFILEINFO.ProductVersionMS
FileVersion = (FileVersionMS >> 16, FileVersionMS & 0xFFFF, FileVersionLS >> 16, FileVersionLS & 0xFFFF)
ProductVersion = (ProductVersionMS >> 16, ProductVersionMS & 0xFFFF, ProductVersionLS >> 16, ProductVersionLS & 0xFFFF)
print 'File version: %s.%s.%s.%s' % FileVersion
print 'Product version: %s.%s.%s.%s' % ProductVersion
但是!这还不是全部:你至少还有一个地方可以查找版本号:在名为OPTIONAL_HEADER的另一个结构内,你可以找到另外两个值,分别称为MajorImageVersion和MinorImageVersion。它们代表了整个版本号的前两部分,因此,一个具有ProductVersion或FileVersion为6.1.7600.150的文件通常会具有MajorImageVersion为6,MinorImageVersion为1。你可以使用pe.OPTIONAL_HEADER.MajorImageVersion
和pe.OPTIONAL_HEADER.MinorImageVersion
来获取它们。
所有这些值(如果我算得对的话,有5个不同的值)通常是等价的(如果忽略掉字符串表中那些额外的自由格式字符串值),但看到不同的FileVersions和ProductVersions也很常见,你也应该准备好面对其他的“惊喜”。
pe.VS_FIXEDFILEINFO.FileVersionLS
应该是 pe.VS_FIXEDFILEINFO[0].FileVersionLS
等等。因为它们是列表。在这个旧版本中可能不是这样的! - undefinedpe.FileInfo[0].StringTable[0].entries['FileVersion']
和pe.FileInfo[0].StringTable[0].entries['ProductVersion']
对我来说都会出现AttributeError: 'list' object has no attribute 'StringTable'
(使用Python 3.10.5和pefile 2022.5.30)。 - undefinedimport win32api
try:
info = win32api.GetFileVersionInfo('rpmsrv.exe', "\\")
ms = info['FileVersionMS']
ls = info['FileVersionLS']
__version__ = "%d.%d.%d.%d" % (win32api.HIWORD(ms), win32api.LOWORD (ms),
win32api.HIWORD (ls), win32api.LOWORD (ls))
except:
__version__ = '5.1.1.000' # some appropriate default here.
--- 包含注释 ---
这需要安装Python的Windows绑定。可以在此处获取:http://starship.python.net/~skippy/win32/。这也限制了该解决方案仅适用于Windows平台(这可能是最终项目中重要因素或不重要因素)。
struct
模块。它非常适用于读取二进制文件。如果你想要更强大的功能,还有一个叫做construct
的包,它更加灵活,但是如果你需要使用它,可能需要更多关于二进制格式的经验。 - undefined