Find Version of Binary File
Question: 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](http://www.linuxquestions.org/questions/programming-9/reading-binary-
file-in-python-804296/):

    
    
    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


Answer: 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.

