@@ -0,0 +1,2697 @@
+%0Afrom ctypes import *%0A%0A# returns the requested version information from the given file%0A#%0A# %60language%60 should be an 8-character string combining both the language and%0A# codepage (such as %22040904b0%22); if None, the first language in the translation%0A# table is used instead%0A#%0Adef get_version_string(filename, what, language=None):%0A    # VerQueryValue() returns an array of that for VarFileInfo%5CTranslation%0A    #%0A    class LANGANDCODEPAGE(Structure):%0A        _fields_ = %5B%0A            (%22wLanguage%22, c_uint16),%0A            (%22wCodePage%22, c_uint16)%5D%0A%0A    wstr_file = wstring_at(filename)%0A%0A    # getting the size in bytes of the file version info buffer%0A    size = windll.version.GetFileVersionInfoSizeW(wstr_file, None)%0A    if size == 0:%0A        raise WinError()%0A%0A    buffer = create_string_buffer(size)%0A%0A    # getting the file version info data%0A    if windll.version.GetFileVersionInfoW(wstr_file, None, size, buffer) == 0:%0A        raise WinError()%0A%0A    # VerQueryValue() wants a pointer to a void* and DWORD; used both for%0A    # getting the default language (if necessary) and getting the actual data%0A    # below%0A    value = c_void_p(0)%0A    value_size = c_uint(0)%0A%0A    if language is None:%0A        # file version information can contain much more than the version%0A        # number (copyright, application name, etc.) and these are all%0A        # translatable%0A        #%0A        # the following arbitrarily gets the first language and codepage from%0A        # the list%0A        ret = windll.version.VerQueryValueW(%0A            buffer, wstring_at(r%22%5CVarFileInfo%5CTranslation%22),%0A            byref(value), byref(value_size))%0A%0A        if ret == 0:%0A            raise WinError()%0A%0A        # value points to a byte inside buffer, value_size is the size in bytes%0A        # of that particular section%0A%0A        # casting the void* to a LANGANDCODEPAGE*%0A        lcp = cast(value, POINTER(LANGANDCODEPAGE))%0A%0A        # formatting language and codepage to something like %22040904b0%22%0A        language = %22%7B0:04x%7D%7B1:04x%7D%22.format(%0A            lcp.contents.wLanguage, lcp.contents.wCodePage)%0A%0A    # getting the actual data%0A    res = windll.version.VerQueryValueW(%0A        buffer, wstring_at(%22%5C%5CStringFileInfo%5C%5C%22 + language + %22%5C%5C%22 + what),%0A        byref(value), byref(value_size))%0A%0A    if res == 0:%0A        raise WinError()%0A%0A    # value points to a string of value_size characters, minus one for the%0A    # terminating null%0A    return wstring_at(value.value, value_size.value - 1)%0A%0A%0Adef main():%0A    filepath = r%22C:%5CProgram Files%5C7-Zip%5C7z.exe%22%0A    version_str = get_version_string(filepath, %22FileVersion%22)%0A    #version_str = get_version_string(filepath, %22ProductVersion%22)%0A    print(version_str)%0A%0Aif __name__ == %22__main__%22:%0A    main()%0A

add working ctypes extraction for file version