VerQueryValueW issue python 3



我正在尝试通过GetFileVersionInfoSizeW和VerQueryValueW获取文件版本。我打印了部分版本,但不是整个版本。它在文件版本的每个字符之间也有一些奇怪的空格。有人知道它有什么问题吗?

我的猜测是它与python3的Unicode解释有关,因为我不得不将GetFileVersionInfoSizeW和VerQueryValueW从在python2(https://stackoverflow.com/a/38924793/7144869)中正常运行的原始GetFileVersionInfoSizeA和VerQueryValueA更改为GetFileVersionInfoSizeA和VerQueryValueA。

import array
from ctypes import *
def get_file_info(filename):
"""
Extract information from a file.
"""
# Get size needed for buffer (0 if no info)
size = windll.version.GetFileVersionInfoSizeW(filename, None)
# If no info in file -> empty string
if not size:
return 'Failed'
# Create buffer
res = create_string_buffer(size)
# Load file informations into buffer res
windll.version.GetFileVersionInfoW(filename, None, size, res)
r = c_uint()
l = c_uint()
# Look for codepages
windll.version.VerQueryValueW(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.VerQueryValueW(res, ('\StringFileInfo\%04x%04x\'
+ 'FileVersion') % codepage, byref(r), byref(l))
return string_at(r.value, l.value)
print (get_file_info(r'C:WINDOWSsystem32calc.exe').decode())

这些函数返回Microsoft所谓的"Unicode"字符串,但实际上是编码的 UTF-16LE,ctypes.wstring可以转换。l.value是 UTF16 字符的计数,而不是字节数,因此请使用以下命令正确解码它。您不需要像现在这样.decode()结果。

return wstring_at(r.value, l.value)

这是我的工作代码:

from ctypes import *
from ctypes import wintypes as w
ver = WinDLL('version')
ver.GetFileVersionInfoSizeW.argtypes = w.LPCWSTR, w.LPDWORD
ver.GetFileVersionInfoSizeW.restype = w.DWORD
ver.GetFileVersionInfoW.argtypes = w.LPCWSTR, w.DWORD, w.DWORD, w.LPVOID
ver.GetFileVersionInfoW.restype = w.BOOL
ver.VerQueryValueW.argtypes = w.LPCVOID, w.LPCWSTR, POINTER(w.LPVOID), w.PUINT
ver.VerQueryValueW.restype = w.BOOL
def get_file_info(filename):
size = ver.GetFileVersionInfoSizeW(filename, None)
if not size:
raise RuntimeError('version info not found')
res = create_string_buffer(size)
if not ver.GetFileVersionInfoW(filename, 0, size, res):
raise RuntimeError('GetFileVersionInfoW failed')
buf = w.LPVOID()
length = w.UINT()
# Look for codepages
if not ver.VerQueryValueW(res, r'VarFileInfoTranslation', byref(buf), byref(length)):
raise RuntimeError('VerQueryValueW failed to find translation')
if length.value == 0:
raise RuntimeError('no code pages')
codepages = array.array('H', string_at(buf.value, length.value))
codepage = tuple(codepages[:2])
# Extract information
if not ver.VerQueryValueW(res, rf'StringFileInfo{codepage[0]:04x}{codepage[1]:04x}FileVersion', byref(buf), byref(length)):
raise RuntimeError('VerQueryValueW failed to find file version')
return wstring_at(buf.value,length.value)
print(get_file_info(r'c:windowssystem32calc.exe'))

输出:

10.0.19041.1 (WinBuild.160101.0800)

最新更新