You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

简化Python的Ctypes联合类型(仅保留Windows键盘事件代码)

Got it, let's fix this for you! The issue you're running into is that the original code probably relied on a union type to handle both mouse and keyboard inputs for the Windows SendInput API, but we can completely strip out all mouse-related code by restructuring how we define the input structures.

Here's the stripped-down, keyboard-only version of your script

This code removes all mouse-related classes/constants and only keeps what's needed to send keyboard presses:

import ctypes
import time

# Load only the necessary Windows API components
user32 = ctypes.WinDLL('user32', use_last_error=True)

# Keyboard-specific constants
INPUT_KEYBOARD = 1
KEYEVENTF_KEYUP = 0x0002

# Define ONLY the keyboard input structure
class KEYBDINPUT(ctypes.Structure):
    _fields_ = [
        ("wVk", ctypes.c_ushort),    # Virtual-key code
        ("wScan", ctypes.c_ushort),  # Hardware scan code (we can leave this 0)
        ("dwFlags", ctypes.c_ulong), # Input flags
        ("time", ctypes.c_ulong),    # Timestamp (unused here)
        ("dwExtraInfo", ctypes.POINTER(ctypes.c_ulong)) # Extra info (unused)
    ]

# Define the INPUT structure to only hold keyboard data (no union needed!)
class INPUT(ctypes.Structure):
    _fields_ = [
        ("type", ctypes.c_ulong),    # Mark this as a keyboard input
        ("ki", KEYBDINPUT)           # Directly embed the keyboard input data
    ]

def press_key(key_code):
    """Simulate pressing a key down"""
    input_down = INPUT()
    input_down.type = INPUT_KEYBOARD
    input_down.ki.wVk = key_code
    input_down.ki.dwFlags = 0  # No flags = key press
    user32.SendInput(1, ctypes.byref(input_down), ctypes.sizeof(INPUT))

def release_key(key_code):
    """Simulate releasing a key"""
    input_up = INPUT()
    input_up.type = INPUT_KEYBOARD
    input_up.ki.wVk = key_code
    input_up.ki.dwFlags = KEYEVENTF_KEYUP  # Flag to signal key release
    user32.SendInput(1, ctypes.byref(input_up), ctypes.sizeof(INPUT))

def send_key(key_code):
    """Send a full key press (down + up)"""
    press_key(key_code)
    release_key(key_code)

# Default to F15 (virtual key code 0x7E)
DEFAULT_KEY = 0x7E

def main(interval_seconds=5, key_code=DEFAULT_KEY):
    print(f"Starting to send key (0x{key_code:02X}) every {interval_seconds} seconds...")
    print("Press Ctrl+C to stop.")
    try:
        while True:
            send_key(key_code)
            print(f"Sent key at {time.strftime('%Y-%m-%d %H:%M:%S')}")
            time.sleep(interval_seconds)
    except KeyboardInterrupt:
        print("\nStopped.")

if __name__ == "__main__":
    # Customize interval or key code here if needed (e.g., main(3, 0x7B) for F12 every 3s)
    main()

Why this works (and why your previous attempts failed)

When you removed the _INPUTunion and MOUSEINPUT before, you probably broke the memory layout that the SendInput API expects. The original union let the API read either mouse or keyboard data from the same memory space.

In this version:

  • We've rewritten the INPUT structure to directly embed the KEYBDINPUT instead of using a union. Since we only ever send keyboard inputs, the type field is always set to INPUT_KEYBOARD, which tells the API exactly how to interpret the data.
  • All mouse-related constants, classes, and logic are completely removed—no extra bloat.
  • The SendInput call works exactly as before because the memory layout of our custom INPUT structure matches what the API expects for keyboard inputs.

Quick notes

  • To use a different key, replace DEFAULT_KEY with the correct virtual key code (e.g., 0x70 for F1, 0x41 for 'A').
  • The script runs until you press Ctrl+C to stop it.

内容的提问来源于stack exchange,提问作者Jean-Francois T.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:56:29