import ctypes

class VS_FIXEDFILEINFO(ctypes.Structure):
    _fields_ = [
        ("dwSignature",         ctypes.c_uint32),
        ("dwStrucVersion",      ctypes.c_uint32),
        ("dwFileVersionMS",     ctypes.c_uint32),
        ("dwFileVersionLS",     ctypes.c_uint32),
        ("dwProductVersionMS",  ctypes.c_uint32),
        ("dwProductVersionLS",  ctypes.c_uint32),
        ("dwFileFlagsMask",     ctypes.c_uint32),
        ("dwFileFlags",         ctypes.c_uint32),
        ("dwFileOS",            ctypes.c_uint32),
        ("dwFileType",          ctypes.c_uint32),
        ("dwFileSubType",       ctypes.c_uint32),
        ("dwFileDateMS",        ctypes.c_uint32),
        ("dwFileDateLS",        ctypes.c_uint32),
        ]

class LANGANDCODEPAGE(ctypes.Structure):
    _fields_ = [
        ("wLanguage",           ctypes.c_uint16),
        ("wCodePage",           ctypes.c_uint16),
        ]

def get_fileversion(filename, stringname="FileVersion"):
    filename = str(filename)
    
    dummy = ctypes.c_uint32(12345)
    length = ctypes.windll.version.GetFileVersionInfoSizeA(filename, ctypes.addressof(dummy))
    
    block = ctypes.create_string_buffer(length+1)
    ret = ctypes.windll.version.GetFileVersionInfoA(filename, ctypes.c_uint32(0), length, block)
    
    p_lang_codepage = ctypes.POINTER(LANGANDCODEPAGE)()
    lang_codepage_length = ctypes.c_uint32()
    ret = ctypes.windll.version.VerQueryValueA(block, "\\VarFileInfo\\Translation", ctypes.addressof(p_lang_codepage), ctypes.addressof(lang_codepage_length))
    lang_codepage = p_lang_codepage.contents
    
    p_result = ctypes.c_char_p()
    result_length = ctypes.c_uint32()
    ret = ctypes.windll.version.VerQueryValueA(block, "\\StringFileInfo\\%04x%04x\\%s" % (lang_codepage.wLanguage, lang_codepage.wCodePage, stringname), ctypes.addressof(p_result), ctypes.addressof(result_length))
    
    return p_result.value
