查找二进制文件版本

3 投票
2 回答
9988 浏览
提问于 2025-04-16 17:36

有没有人知道我怎么才能找到传给我函数的二进制文件的版本呢?

我从这个页面上得到了以下代码:

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

    s = f.read(1024)
    print s

    f.close()

不过,这段代码并没有给我任何有用的输出,跟那个网站上显示的结果不一样。

编辑:@BoazYaniv告诉我,文件格式在这个问题中很重要。这是一个Windows的EXE文件。

2 个回答

12

你可以使用一个现成的模块来解析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位整数的形式存储,每个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。你可以通过pe.OPTIONAL_HEADER.MajorImageVersionpe.OPTIONAL_HEADER.MinorImageVersion来获取它们。

所有这些值(如果我没算错的话,一共5个不同的值)通常是相等的(如果你忽略字符串表中有的额外自由格式字符串),但常常会看到FileVersion和ProductVersion不一样的情况,你也应该做好遇到其他意外的准备。

5

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

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.

--- 下面是一些注释 ---

这需要在你的电脑上安装Python的Windows绑定。你可以在这里找到它们:http://starship.python.net/~skippy/win32/。这也意味着这个解决方案只能在Windows系统上使用(这可能对最终项目来说是个重要因素,也可能不是)。

撰写回答