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

基于Win32api向未聚焦窗口模拟Key Press的脚本实现咨询

Absolutely, this is totally achievable! The core issue with your current script is that it’s tied to the focused window for input—but we can fix this by sending keyboard events directly to the target window’s underlying handle, regardless of whether it’s in the background, minimized, or unfocused. Let’s break down how to implement this across major operating systems with practical, working code examples.

Windows Platform

On Windows, the most reliable way to send keystrokes to a background window is using the PostMessage API, which lets you send WM_KEYDOWN and WM_KEYUP messages directly to a window’s handle (HWND). Here’s a Python example using the pywin32 library:

import win32gui
import win32api
import win32con
import time

def send_key_to_window(window_title, key_code):
    # Locate the target window by its title
    hwnd = win32gui.FindWindow(None, window_title)
    if not hwnd:
        print(f"Window '{window_title}' not found—double-check the title!")
        return
    
    # Simulate key press (WM_KEYDOWN)
    win32api.PostMessage(hwnd, win32con.WM_KEYDOWN, key_code, 0)
    time.sleep(0.1)  # Mimic natural key hold duration
    # Simulate key release (WM_KEYUP)
    win32api.PostMessage(hwnd, win32con.WM_KEYUP, key_code, 0)

# Example: Send Enter key to Notepad every 2 seconds
while True:
    send_key_to_window("Notepad", win32con.VK_RETURN)
    time.sleep(2)

Notes for Windows:

  • Use win32con.VK_* constants for standard keys (e.g., VK_SPACE, VK_TAB). For character keys, you may need to use MapVirtualKey to convert ASCII to virtual key codes.
  • Some apps (like certain games) block PostMessage—if that’s the case, you can look into SendInput with temporary window focus (but that will briefly bring the window to the foreground).

Linux Platform

On Linux, you can use xdotool (a command-line utility) for quick implementation, or the python-xlib library for more control. Here’s both approaches:

Using xdotool (Command Line)

# Get the target window ID by title
WINDOW_ID=$(xdotool search --name "Your Target Window Title")

# Send Enter key every 2 seconds
while true; do
    xdotool key --window $WINDOW_ID Return
    sleep 2
done

Using Python & python-xlib

from Xlib import X, display
import time

def send_key_to_window(window_title, key_symbol):
    d = display.Display()
    root = d.screen().root
    target_win = None

    # Search for the window by title
    for win in root.query_tree().children:
        try:
            if win.get_wm_name() == window_title:
                target_win = win
                break
        except:
            continue

    if not target_win:
        print(f"Window '{window_title}' not found!")
        return

    # Convert key symbol to keycode
    keycode = d.keysym_to_keycode(key_symbol)
    # Send key press event
    target_win.send_event(X.KeyPressEvent(
        time=X.CurrentTime, root=root, window=target_win,
        same_screen=0, child=X.NONE, root_x=0, root_y=0,
        event_x=0, event_y=0, state=0, detail=keycode
    ))
    time.sleep(0.1)
    # Send key release event
    target_win.send_event(X.KeyReleaseEvent(
        time=X.CurrentTime, root=root, window=target_win,
        same_screen=0, child=X.NONE, root_x=0, root_y=0,
        event_x=0, event_y=0, state=0, detail=keycode
    ))
    d.sync()

# Example: Send Enter key to a Terminal window every 2 seconds
while True:
    send_key_to_window("Terminal", X.K_Return)
    time.sleep(2)

macOS Platform

On macOS, you can use AppleScript for a no-compile solution, or pyobjc to call the Quartz Event Services API. Here’s how:

Using AppleScript

repeat
    tell application "System Events"
        tell process "YourAppName"
            key code 36 -- Keycode for Enter; look up others online
        end tell
    end tell
    delay 2
end repeat

Save this as send_keys.scpt and run it with osascript send_keys.scpt. Note: You’ll need to grant accessibility permissions to your terminal/script runner in System Preferences → Security & Privacy → Privacy → Accessibility.

Using Python & pyobjc

from Quartz import CGEventCreateKeyboardEvent, CGEventPostToPSN, ProcessSerialNumber
import time
import LaunchServices

def send_key_to_window(app_name, key_code):
    # Get the app's process serial number
    psn = ProcessSerialNumber(highLongOfPSN=0, lowLongOfPSN=0)
    if not LaunchServices.LSCopyApplicationURLsForBundleIdentifier(app_name, None):
        print(f"App '{app_name}' not found!")
        return
    LaunchServices.LSFindApplicationForInfo(None, None, app_name, None, psn)

    # Send key press
    down_event = CGEventCreateKeyboardEvent(None, key_code, True)
    CGEventPostToPSN(psn, down_event)
    time.sleep(0.1)
    # Send key release
    up_event = CGEventCreateKeyboardEvent(None, key_code, False)
    CGEventPostToPSN(psn, up_event)

# Example: Send Enter key to TextEdit every 2 seconds
while True:
    send_key_to_window("com.apple.TextEdit", 36)
    time.sleep(2)

General Tips

  • Always test with a simple app (like Notepad/TextEdit/Terminal) first to verify functionality.
  • Key codes vary by platform—look up the correct codes for the keys you need to simulate.
  • Some apps have anti-cheat or input blocking mechanisms that may prevent background input; in those cases, you may need more advanced tools or hooks.

内容的提问来源于stack exchange,提问作者user5457708

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 07:25:22