查找二进制文件的版本

时间:2011-05-13 19:12:47

标签: python version binaryfiles

有谁知道如何找到已传递给我的函数的二进制文件的版本?

我从this page获得了以下代码:

def version(fpath):
    f = open(fpath, 'rb')

    s = f.read(1024)
    print s

    f.close()

然而,这并没有给我任何类似于上述网站显示的有用输出。

编辑:@BoazYaniv告诉我文件格式在此问题中起着重要作用。这是一个Windows EXE文件

2 个答案:

答案 0 :(得分:7)

您有一个用于解析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中的WORD)。总而言之,每个版本值(FileVersion和ProductVersion)都有4个16位WORD,它们代表版本的点分隔部分。您也可以使用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.您可以使用{{1}获取它们}和pe.OPTIONAL_HEADER.MajorImageVersion

所有这些值(5个不同的值,如果我算得正确的话)通常都是等价的(如果你忽略了字符串表中有时会有的额外的自由形式字符串值),但是看到FileVersions和ProductVersions很常见。不一样,你也应该为其他的惊喜做好准备。

答案 1 :(得分:4)

我们使用此代码从我们的某个可执行文件中提取版本,以便在其他程序中使用。

import 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.

---包含评论---

这需要安装Windows Bindings for Python。他们可以在这里找到:http://starship.python.net/~skippy/win32/。这也将此解决方案限制在Windows平台上(这可能是也可能不是最终项目中的重要因素)。