tags:

views:

62

answers:

2

Basically i am trying to find out what version of ArcGIS the user currently has installed, i looked through the registry and couldn't find anything related to a version string. However i know it is stored, within the .exe.

I've done a fair bit of googling, and can't find anything really worth it. I tried using the GetFileVersionInfo, and i seem to get a random mishmash of stuff.

Any ideas?

EDIT

Sigh....

Turns out pywin32 is not always installed on all machines. Does anyone know if its possible to do the same thing via ctypes?

Also this is only for windows.

A: 

there's a gnu linux utility called 'strings' that prints the printable characters in any file(binary or non-binary), try using that and look for a version number like pattern

on windows, you can get strings here http://unxutils.sourceforge.net/

Charles Ma
+1  A: 

If you prefer not to do this using pywin32, you would be able to do this with ctypes, for sure.

The trick will be decoding that silly file version structure that comes back.

There's one old mailing list post that is doing what you're asking. Unfortunately, I don't have a windows box handy to test this myself, right now. But if it doesn't work, it should at least give you a good start.

Here's the code, in case those 2006 archives vanish sometime:

import array
from ctypes import *

def get_file_info(filename, info):
    """
    Extract information from a file.
    """
    # Get size needed for buffer (0 if no info)
    size = windll.version.GetFileVersionInfoSizeA(filename, None)
    # If no info in file -> empty string
    if not size:
        return ''
    # Create buffer
    res = create_string_buffer(size)
    # Load file informations into buffer res
    windll.version.GetFileVersionInfoA(filename, None, size, res)
    r = c_uint()
    l = c_uint()
    # Look for codepages
    windll.version.VerQueryValueA(res, '\\VarFileInfo\\Translation',
                                  byref(r), byref(l))
    # If no codepage -> empty string
    if not l.value:
        return ''
    # Take the first codepage (what else ?)
    codepages = array.array('H', string_at(r.value, l.value))
    codepage = tuple(codepages[:2].tolist())
    # Extract information
    windll.version.VerQueryValueA(res, ('\\StringFileInfo\\%04x%04x\\'
+ info) % codepage, byref(r), byref(l))
    return string_at(r.value, l.value)

print get_file_info(r'C:\WINDOWS\system32\calc.exe', 'FileVersion')

--

Ok - back near a windows box. Have actually tried this code now. "Works for me".

>>> print get_file_info(r'C:\WINDOWS\system32\calc.exe', 'FileVersion')
6.1.7600.16385 (win7_rtm.090713-1255)
otherchirps