查找二进制文件版本
有没有人知道我怎么才能找到传给我函数的二进制文件的版本呢?
我从这个页面上得到了以下代码:
def version(fpath):
f = open(fpath, 'rb')
s = f.read(1024)
print s
f.close()
不过,这段代码并没有给我任何有用的输出,跟那个网站上显示的结果不一样。
编辑:@BoazYaniv告诉我,文件格式在这个问题中很重要。这是一个Windows的EXE文件。
2 个回答
你可以使用一个现成的模块来解析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.MajorImageVersion
和pe.OPTIONAL_HEADER.MinorImageVersion
来获取它们。
所有这些值(如果我没算错的话,一共5个不同的值)通常是相等的(如果你忽略字符串表中有的额外自由格式字符串),但常常会看到FileVersion和ProductVersion不一样的情况,你也应该做好遇到其他意外的准备。
我们用这段代码从我们的一个可执行文件中提取版本信息,以便在其他程序中使用。
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系统上使用(这可能对最终项目来说是个重要因素,也可能不是)。