Python Block Keyboard / Mouse Input

Question:

i am currently trying to write a short script that will rickroll (open a youtube link) while the user is watching and can’t interfere.
I have managed to open insert the link slowly letter by letter and am now trying to block user inputs.
I have tried using the ctypes import to block all inputs, run the script and then unblock again, but it somehow won’t block the input. I’m just receiving my RuntimeError message.
How do i fix it, so the inputs get blocked?
Thanks in advance!
Heres the code:

import subprocess
import pyautogui
import time
import ctypes
from ctypes import wintypes

BlockInput = ctypes.windll.user32.BlockInput
BlockInput.argtypes = [wintypes.BOOL]
BlockInput.restype = wintypes.BOOL

blocked = BlockInput(True)

if blocked:
    try:
        subprocess.Popen(["C:\Program Files\Google\Chrome\Application\chrome.exe",])
        time.sleep(3)
        pyautogui.write('www.youtube.com/watch?v=DLzxrzFCyOs', interval= 0.5)
        pyautogui.hotkey('enter')
    finally:
        unblocked = BlockInput(False)
else:
    raise RuntimeError('Input is already blocked by another thread')
Asked By: señor.woofers

||

Answers:

You can use the keyboard module to block all keyboard inputs and the mouse module to constantly move the mouse, preventing the user from moving it.

See these links for more details:

https://github.com/boppreh/keyboard

https://github.com/boppreh/mouse

This blocks all the keys on the keyboard (the 150 is large enough to ensure all keys are blocked).

#### Blocking Keyboard ####
import keyboard

#blocks all keys of keyboard
for i in range(150):
    keyboard.block_key(i)

This effectively blocks mouse-movement by constantly moving the mouse to position (1,0).

#### Blocking Mouse-movement ####
import threading
import mouse
import time

global executing
executing = True

def move_mouse():
    #until executing is False, move mouse to (1,0)
    global executing
    while executing:
        mouse.move(1,0, absolute=True, duration=0)

def stop_infinite_mouse_control():
    #stops infinite control of mouse after 10 seconds if program fails to execute
    global executing
    time.sleep(10)
    executing = False

threading.Thread(target=move_mouse).start()

threading.Thread(target=stop_infinite_mouse_control).start()
#^failsafe^

And then your original code here (the if statement and try/catch block are no longer necessary).

#### opening the video ####
import subprocess
import pyautogui
import time

subprocess.Popen(["C:\Program Files\Google\Chrome\Application\chrome.exe",])
time.sleep(3)
pyautogui.write('www.youtube.com/watch?v=DLzxrzFCyOs', interval = 0.5)
pyautogui.hotkey('enter')


#### stops moving mouse to (1,0) after video has been opened
executing = False

Just a few notes:

  1. The mouse-moving is hard to stop from outside of the program (it’s basically impossible to close the program when it is executing, especially as the keyboard is also being blocked), that’s why I put in the failsafe, which stops moving the mouse to (1,0) after 10 seconds.
  2. (On Windows) Control-Alt-Delete does allow Task Manager to be opened and then the program can be force-stopped from there.
  3. This doesn’t stop the user from clicking the mouse, which can sometimes prevent the YouTube link from being typed in full (i.e. a new tab can be opened)

See a full version of the code here:

https://pastebin.com/WUygDqbG

Answered By: John Skeen

you could do something like this to block both keyboard and mouse input

    from ctypes import windll
    from time import sleep
    
    windll.user32.BlockInput(True) #this will block the keyboard input
    sleep(15) #input will be blocked for 15 seconds
    windll.user32.BlockInput(False) #now the keyboard will be unblocked
Answered By: hi im lost

Here’s a function for blocking keyboard and mouse input. You can pass a number to the blockMouseAndKeys function to adjust the timeout period:

import os
import time
import pyautogui
from threading import Thread
from keyboard import block_key

def blockMouseAndKeys(timeout=5):
    global blocking
    blockStartTime = time.time()
    pyautogui.FAILSAFE = False
    blocking = True
    try: float(timeout)
    except: timeout = 5

    def blockKeys(timeout):
        global blocking
        while blocking:
            if timeout:
                if time.time()-blockStartTime > timeout:
                    print(f'Keyboard block timed out after {timeout}s.')
                    return
            for i in range(150):
                try: block_key(i)
                except: pass
    def blockMouse(timeout):
        global blocking
        while blocking:
            def resetMouse(): pyautogui.moveTo(5,5)
            Thread(target=resetMouse).start()
            if timeout:
                if time.time()-blockStartTime > timeout:
                    print(f'Mouse block timed out after {timeout}s.')
                    return
    def blockTimeout(timeout):
        global blocking
        time.sleep(timeout)
        blocking = False
        pyautogui.FAILSAFE = False
        print('Done blocking inputs!')

    print('Blocking inputs...')
    Thread(target=blockKeys, args=[timeout]).start()
    Thread(target=blockMouse, args=[timeout]).start()
    Thread(target=blockTimeout, args=[timeout]).start()


blockMouseAndKeys(timeout=10)
os.startfile('https://www.youtube.com/watch?v=DLzxrzFCyOs')
Answered By: Ty Lane
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.