Кто-нибудь знает, как я могу найти версию двоичного файла, который был передан моей функции?
Я получил следующий код эту страницу:
def version(fpath):
f = open(fpath, 'rb')
s = f.read(1024)
print s
f.close()
Однако это не дает мне полезного результата, аналогичного тому, что показывает указанный веб-сайт.
Изменить: @BoazYaniv говорит мне, что формат файла играет важную роль в этой проблеме. Это файл Windows EXE
Мы используем этот код для вытягивания версий из одного из наших исполняемых файлов для использования в других программах.
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 для Python. Они доступны здесь: http://starship.python.net/~skippy/win32/. Это также ограничивает это решение для платформ 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 могут сохранить версию. Есть два дополнительных значения FileVersion и ProductVersion, хранящиеся в EXE, только они хранятся в виде пар из 32-разрядных целых чисел, каждый из которых, в свою очередь, разбивается на два 16-битных целых числа (WORDs в Windows API говорят). В целом, каждое значение версии (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 разных, если я считаю их правильными) обычно эквивалентны (если вы игнорируете дополнительное строковое значение свободной формы, которое иногда имеет значение в таблице строк), но его довольно часто встречаются, чтобы увидеть файлы и файлы ProductVersions, которые не то же самое, и вы также должны быть готовы к другим неожиданностям.