This quick-and-dirty recipe fetches the version number from a Win32 PE file without the need for the win32 API. It is therefore suitable for execution on non-Windows platform.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
def get_version_from_win32_pe(file): # http://windowssdk.msdn.microsoft.com/en-us/library/ms646997.aspx sig = struct.pack("32s", u"VS_VERSION_INFO".encode("utf-16-le")) # This pulls the whole file into memory, so not very feasible for # large binaries. try: filedata = open(file).read() except IOError: return "Unknown" offset = filedata.find(sig) if offset == -1: return "Unknown" filedata = filedata[offset + 32 : offset + 32 + (13*4)] version_struct = struct.unpack("13I", filedata) ver_ms, ver_ls = version_struct, version_struct return "%d.%d.%d.%d" % (ver_ls & 0x0000ffff, (ver_ms & 0xffff0000) >> 16, ver_ms & 0x0000ffff, (ver_ls & 0xffff0000) >> 16)
Most of the examples online were not only unwieldy but also required access to the win32 API (for GetFileVersionInfo). This snippet is small and understandable, and it has no platform-specific requirements. The main disadvantage of this code is that it reads the whole Win32 binary into memory, so for large executables this may not be desirable, though it should be fairly easy to adapt to be less memory hungry.
It should also be easy to modify the function to expose more data from the VS_FIXEDFILEINFO structure.