如何进一步调试sendKeysTypes(win7 64位,py2.7)?

2024-05-15 00:51:40 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试让SendKeysTypes工作在py2.7和win7 64位上。Here is src

问题:

运行SendKeysCtypes.py,什么都没有发生。测试应该打开记事本并写一些文本。在

问题代码是:

def GetInput(self):
    "Build the INPUT structure for the action"
    actions = 1
    # if both up and down
    if self.up and self.down:
        actions = 2

    inputs = (INPUT * actions)()

    vk, scan, flags = self._get_key_info()

    for inp in inputs:
        inp.type = INPUT_keyboard

        inp._.ki.wVk = vk
        inp._.ki.wScan = scan
        inp._.ki.dwFlags |= flags

    # if we are releasing - then let it up
    if self.up:
        inputs[-1]._.ki.dwFlags |= KEYEVENTF_KEYUP

    return inputs

def Run(self):
    "Execute the action"
    inputs = self.GetInput()
    return SendInput(
        len(inputs),
        ctypes.byref(inputs),
        ctypes.sizeof(INPUT))

上面代码中的SendInput()不执行任何操作。在

其他测试

在这里我们陷入困境,因为我的windows编程非常有限,有人能解释一下吗?在

编辑1:

  • 在“64bit is problem”跟踪之后,引导我到这个SO question,看看我是否可以转换它。在

Tags: the代码selfactionsinputifisdef
1条回答
网友
1楼 · 发布于 2024-05-15 00:51:40

您使用的StructureUnion类有两个问题。我将用the code you linked to中的一个类重新生成一个片段,如下所示:

class KEYBDINPUT(ctypes.Structure):
    "A particular keyboard event"
    _pack_ = 2  # FIXME: don't do this
    _fields_ = [
        # C:/PROGRA~1/MICROS~4/VC98/Include/winuser.h 4292
        ('wVk', WORD),
        ('wScan', WORD),
        ('dwFlags', DWORD),
        ('time', DWORD),
        ('dwExtraInfo', DWORD),  # FIXME: use correct data type
    ]

(我添加了修复程序以指出有问题的部分。)

第一种情况是您使用的是_pack_ = 2,这是不正确的。您根本不应该使用任何_pack_对齐说明符。默认值在32位和64位Windows上都可以正常工作。在

它与32位Windows上的_pack_ = 2一起工作纯粹是偶然的:代码中使用的所有2字节大小的数据类型成对出现,并且从已经对齐的边界开始,因此碰巧产生了与4字节对齐相同的结构。在

但是,在64位窗口下,基本对齐是8字节,因此如果在那里使用_pack_ = 2_pack_ = 4,则结构将不对齐并具有错误的大小。在

第二个问题是ctypes.wintypes中没有ULONG_PTR,这将是dwExtraInfo的正确数据类型。在32位Windows下,ULONG_PTR是一个无符号的32位整数,而在64位Windows下,它是一个无符号的64位整数。在

MSDN article about Windows Data Types显示了它的定义:

^{pr2}$

因此,使用DWORDULONG表示dwExtraInfo,因此只在32位窗口下工作,否则会产生错误的大小。在

虽然使用某些基于POINTER的数据类型会碰巧生成一个对齐和大小正确的结构,但无论在意义上还是在用法上都是错误的,因为ULONG_PTR是“一个可以存储(casted)指针的无符号整数”,而不是实际的指针。在

浏览wintypes,您会注意到WPARAM的定义恰好与ULONG_PTR的定义完全相同。因此,一个快速而肮脏(但仍然相当健壮)的方法是:

from ctypes.wintypes import WPARAM as ULONG_PTR

或者,您可以使用一段受他们启发的代码,然后自己定义:

import ctypes

for ULONG_PTR in [ctypes.c_ulong, ctypes.c_ulonglong]:
    if ctypes.sizeof(ULONG_PTR) == ctypes.sizeof(ctypes.c_void_p):
        break
else:
    raise TypeError("cannot find a suitable type for ULONG_PTR")

有了这些适应性,您可以定义如下结构:

class MOUSEINPUT(ctypes.Structure):
    _fields_ = [
        ('dw',          LONG),
        ('dy',          LONG),
        ('mouseData',   DWORD),
        ('dwFlags',     DWORD),
        ('time',        DWORD),
        ('dwExtraInfo', ULONG_PTR),
    ]


class KEYBDINPUT(ctypes.Structure):
    _fields_ = [
        ('wVk',         WORD),
        ('wScan',       WORD),
        ('dwFlags',     DWORD),
        ('time',        DWORD),
        ('dwExtraInfo', ULONG_PTR),
    ]


class HARDWAREINPUT(ctypes.Structure):
    _fields_ = [
        ('uMsg',    DWORD),
        ('wParamL', WORD),
        ('wParamH', WORD),
    ]


class _INPUT(ctypes.Union):
    _fields_ = [
        ('mi', MOUSEINPUT),
        ('ki', KEYBDINPUT),
        ('hi', HARDWAREINPUT),
    ]


class INPUT(ctypes.Structure):
    _anonymous_ = ['']
    _fields_ = [
        ('type', DWORD),
        ('', _INPUT),
    ]

相关问题 更多 >

    热门问题