查找二进制文件的版本

发布于 2024-11-06 18:37:28 字数 415 浏览 2 评论 0原文

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

我从 此页面:

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

    s = f.read(1024)
    print s

    f.close()

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

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

Does anyone know how I can find the version of a binary file that has been passed to my function?

I got the following code from this page:

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

    s = f.read(1024)
    print s

    f.close()

However, this does not give me any useful output similar to what the mentioned website shows.

Edit: @BoazYaniv tells me that the file format plays in important part in this problem. This is a windows EXE file

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

海夕 2024-11-13 18:37:29

您有一个用于解析 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 位字,表示版本的点分隔部分。您也可以使用 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 个不同的值,如果我数对的话)通常是等效的(如果您忽略字符串表中的值有时具有的额外自由格式字符串值),但看到 FileVersions 和 ProductVersions 不相同的情况很常见,并且您还应该准备好迎接其他惊喜。

You have a ready-made module for parsing EXE files:
http://code.google.com/p/pefile/

You could read it using the following code:

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']

As you can see, Windows EXE (and DLL) files store two different kinds of versions, FileVersion and ProductVersion. Many times they are the same, but sometimes they may different - it all depends on the one who made the EXE really.

Edit:

Just to make things more complex, these two strings in the PE string table aren't the only place where Windows compilers may save the version. There are two addiotnal FileVersion and ProductVersion values stored in the EXE, only they are stored as pairs of 32-bit integers, each of them is broken, in turn, into two 16-bit integers (WORDs in Windows API speak). Altogether, each version value (FileVersion and ProductVersion) has 4 16-bit WORDs which represent the dot-separated parts of the version. You can get them too, using 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

But wait! This is not all: you have at least one more place where you could look to find the version: Inside another structure, called OPTIONAL_HEADER, you can find another two values called MajorImageVersion and MinorImageVersion. They represent the two first parts of the whole version, so a file which has a ProductVersion or FileVersion of, say, 6.1.7600.150, would usually have a MajorImageVersion of 6 and a MinorImageVersion of 1. You could get them with pe.OPTIONAL_HEADER.MajorImageVersion and pe.OPTIONAL_HEADER.MinorImageVersion.

All these values (5 different ones, if I count them right) are usually equivalent (if you ignore the extra freeform string value the ones at a string table sometimes have), but its quite common to see FileVersions and ProductVersions that are not the same, and you should also be ready for other surprises as well.

鸠书 2024-11-13 18:37:29

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

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 平台(这可能是也可能不是最终项目中的重要因素)。

We use this code to pull versions from one of our executables for use throughout other programs.

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.

--- To encompass the comments ---

This requires that the Windows Bindings for Python be installed. They're available here: http://starship.python.net/~skippy/win32/. This also limits this solution to Windows platforms (which may or may not be an important factor in the final project).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文