【问题标题】:Executing windll.version.GetFileVersionInfoSizeA() fails in Python 3在 Python 3 中执行 windll.version.GetFileVersionInfoSizeA() 失败
【发布时间】:2019-12-24 06:31:25
【问题描述】:

我正在尝试在 python ctypes 中执行 windll.version.GetFileVersionInfoSizeA()。我正在执行以下代码:

_GetFileVersionInfoSizeA = ctypes.windll.version.GetFileVersionInfoSizeA
_GetFileVersionInfoSizeA.argtypes = [ctypes.c_char_p, ctypes.c_void_p]
_GetFileVersionInfoSizeA.restype = ctypes.c_uint32
_GetFileVersionInfoSizeA.errcheck = RaiseIfZero # RaiseIfZero is a function to raise error
# lptstrFilename is the file path
dwLen = _GetFileVersionInfoSizeA(lptstrFilename, None)

此代码在 python 2 中完美运行,但在 python 3.8 中无法运行。它给出了以下错误:

argument 1: <class 'TypeError'>: wrong type

根据msdn doc对于GetFileVersionInfoSizeA,第二个参数应该是:

“指向函数设置为零的变量的指针。”


我尝试了以下代码,但它给出了与以前相同的错误。

dwLen = _GetFileVersionInfoSizeA(lptstrFilename, LPVOID)

我不确定我错过了什么。
注意 - 这是我第一次使用ctypes

【问题讨论】:

    标签: python python-3.x python-2.7 ctypes python-3.8


    【解决方案1】:

    python2 中可以使用两种类型来表示字符串。 字符串Unicode字符串。因此c_char_p ctypes类型用于表示python2字符串类型和@987654324 @ctypes 类型用于表示python2 unicode 字符串类型

    但在 python3 中只有一种字符串类型。因此c_wchar_p ctypes 类型用于表示python3 string 类型,c_char_p ctypes 类型用于表示python3 bytes 类型。

    您可以在 python 2python 3 文档中找到基本数据类型。

    所以你可以这样做

    dwLen = _GetFileVersionInfoSizeA(your_file_name.encode(), None)
    

    【讨论】:

      【解决方案2】:

      在 Python 3 中,字符串默认为 Unicode。即使在 Python 2 中,它也最好使用 Unicode 字符串,因此 Windows API 的 W 版本本身就是 Unicode。因此,要严格按照文档调用该 API:

      >>> from ctypes import *
      >>> from ctypes import wintypes as w
      >>> dll = WinDLL('api-ms-win-core-version-l1-1-0')
      >>> GetFileVersionInfoSize = dll.GetFileVersionInfoSizeW
      >>> GetFileVersionInfoSize.argtypes = w.LPCWSTR,w.LPDWORD
      >>> GetFileVersionInfoSize.restype = w.DWORD
      >>> GetFileVersionInfoSize('test.exe',byref(w.DWORD())) # create a temporary DWORD passed by reference.
      2316
      

      请注意,第二个参数没有记录为接受 nullptr(在 Python 中也称为 None),因此它应该是一个有效的参考。

      要调用函数的 ANSI(A) 版本,请传递一个以默认 ANSI 编码正确编码的字节字符串,例如'test.exe'.encode('ansi'),但请注意,非 ASCII 文件名会导致问题,但使用 Unicode(W) 版本可以缓解。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-07-21
        • 1970-01-01
        • 1970-01-01
        • 2013-03-01
        • 1970-01-01
        • 2023-03-15
        • 1970-01-01
        相关资源
        最近更新 更多