[Python] Recognize the exact process that sent the keystroke in Python

Discussão em 'Python' iniciado por Stack, Dezembro 21, 2024.

  1. Stack

    Stack Membro Participativo

    I'm trying to build a program that recognizes keystrokes and also the exact process that sent it, so the source.

    For example, if I press the character 'g' on my keyboard, it should recognize the keyboard as the source, since no app sent the keystroke but the keyboard, then if I run an AutoHotkey script which virtually press the character 'w', the program should say "script.ahk", which is the name of the script; if any process sends a keystroke, the program should say that exact process.

    I've tried coding it but ended up on displaying the currently focused window name, not the exact process.

    For example if I'm browsing files in explorer.exe and I double click on the AutoHotkey script, the program says explorer.exe instead of the name of the script.

    Is it possible to do this recognizing process? Or is impossible to detect the exact process that sent the keystroke?

    The code:

    import ctypes
    import psutil
    from pynput.keyboard import Listener as KeyboardListener

    # Function to get the active window's title and hwnd (handle) (Windows-specific)
    def get_active_window_title():
    user32 = ctypes.windll.user32
    GetForegroundWindow = user32.GetForegroundWindow
    GetWindowText = user32.GetWindowTextW
    GetWindowTextLength = user32.GetWindowTextLengthW

    hwnd = GetForegroundWindow()
    length = GetWindowTextLength(hwnd)
    buf = ctypes.create_unicode_buffer(length + 1)
    GetWindowText(hwnd, buf, length + 1)
    return buf.value, hwnd

    # Function to get the process name from the window's hwnd (handle)
    def get_process_name_from_hwnd(hwnd):
    try:
    # Get the process ID using the window's handle
    pid = ctypes.c_ulong(0)
    ctypes.windll.user32.GetWindowThreadProcessId(hwnd, ctypes.byref(pid))

    p = psutil.Process(pid.value)
    return p.name()
    except psutil.NoSuchProcess:
    return None

    # Function to identify whether the key press is from a physical keyboard or an app
    def identify_keypress_source():
    # Get the current active window and its process name
    active_window, hwnd = get_active_window_title()
    process_name = get_process_name_from_hwnd(hwnd)

    # If there's an active window and it's associated with a process, it must be app-generated
    if active_window and process_name:
    return f"app-generated (Process: {process_name})"
    else:
    # If no active window, consider it a physical keyboard input
    return "keyboard"

    # Callback for key press events
    def on_press(key):
    try:
    keystroke_source = identify_keypress_source()

    if hasattr(key, 'char') and key.char:
    print(f"Key '{key.char}' pressed from {keystroke_source}")
    else:
    print(f"Special key {key} pressed from {keystroke_source}")
    except Exception as e:
    print(f"Error occurred: {e}")

    # Function to start the listener for keyboard events
    def start_key_listener():
    with KeyboardListener(on_press=on_press) as listener:
    listener.join()

    if __name__ == "__main__":
    print("Starting key press listener...")

    # Start listening to the keyboard
    start_key_listener()

    Continue reading...

Compartilhe esta Página