【问题标题】:the windows API does not work with python3 but works with python 2windows API 不适用于 python3 但适用于 python 2
【发布时间】:2019-08-12 09:31:34
【问题描述】:

我有一个 python 脚本,我正在尝试将它从 python 2.7 转换为 python 3.7。 该脚本包括用于读取系统注册表的 Windows API。在 python 2.7 中它可以正常工作。在 python 3.7 中,它不会返回正确的结果。

我尝试使用 python 3 在另一台 PC 上运行脚本 python 3。我只在 powershell 中运行脚本,如管理员。 https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regopenkeyexa 这是 RegOpenKeyExA() 函数的文档。 在 python 2.7 中,我从 https://download.microsoft.com/download/7/9/6/796EF2E4-801B-4FC4-AB28-B59FBF6D907B/VCForPython27.msi 安装了“VCForPython27.msi”,对于 windows 3.7,我没有找到更新的版本。

from ctypes import c_uint, c_char_p, byref, windll
subkey = 'JD'    

def RegOpenKeyEx(subkey):
        hkey = c_uint(0) ## Initialize to an int
        windll.advapi32.RegOpenKeyExA(0x80000002, 'SYSTEM\\CurrentControlSet\\Control\\Lsa\\' + subkey, 0, 0xF003F , byref(hkey))
        print(hkey.value)
        return hkey.value

在 python 2.7 中,输出为: 656 而windll.advapi32.RegOpenKeyExA函数返回0作为返回值。

在 python 3.7 中,输出为: 0 而windll.advapi32.RegOpenKeyExA函数返回2作为返回值

【问题讨论】:

  • 您阅读了哪些文档?您的问题可能是整个系统问题,而不是与您的程序相关的问题。请给一些minimal reproducible example
  • 2 是“未找到”错误代码
  • 使用标准库的 winreg 模块(或 2.x 中的 _winreg),这是一个更安全、更高效的 C 扩展。
  • 这个 ctypes 代码使用了错误的类型(句柄不是 unsigned int;它是 void *;碰巧,非负内核句柄在 32 位范围内,并且特殊的负值将被符号扩展到 64 位给定 ctypes 默认 c_int 参数转换),可疑值(幸运的是 ctypes 默认符号扩展为 0x80000002),旧版 ANSI(注册表是 Unicode),并且依赖于 windll 而不是WinDLL("advapi32", use_last_error=True)。全局windll 存在上次错误处理问题以及与使用它的其他库的原型不一致。

标签: python-3.x windows


【解决方案1】:

我解决了将第 6 行替换为:

windll.advapi32.RegOpenKeyExA(0x80000002, 'SYSTEM\\CurrentControlSet\\Control\\Lsa\\'.encode('ascii') + subkey.encode('ascii'), 0, 0x19 , byref(hkey))

在 Python 2.7 中,默认情况下字符串是字节字符串。在 Python 3.x 中,它们默认为 unicode。我使用 .encode('ascii') 明确地将字符串设为字节字符串。

【讨论】:

  • 切换到RegOpenKeyExW并显式设置argtypes(因此它知道转换为LPWSTR)也应该可以工作,支持非ASCII名称,并且不需要显式编码在每个使用点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多