Capturing windows keyboard strokes while script isn't current used process - python

I am trying to make an application that redoes my exact movements on keyboard on a certain process, so I am attempting to register my keyboard strokes time-stamped, I tried to do it using msvcrt or pygame, however they both require keys to be entered to the command prompt itself, else it wont detect it.
Is it possible to create a time-stamped "keylogger" using PYTHON
P.S: I just want to learn more about python scripting.
this is the code i tried:
import msvcrt
import time
import datetime
while True:
char = msvcrt.getch()
print char
print datetime.datetime.now().time()

What you've written is a program that captures inputs to itself. What you need, at least for Windows, are global input hooks. This will allow your application to capture all input to the machine.
Take a look at the following resources:
Windows Hooks Overview
Python for Windows Extensions
PyHook, a Python wrapper for global input hooks

Related

How can I send keystrokes and mouse movement to a specific PID?

How can I send keystrokes and mouse movements to a specific running program through its PID. I've used both pywinauto and pynput, and they work great, but I want to send keys to a program that is not in focus. I found this question: How to I send keystroke to Linux process in Python by PID? but it never explains what filePath is a path to.
If you could help solve for this example, that would be great! I want to send the "d" key to an open Minecraft tab for 10 seconds, and then send the "a" key for the next 10 seconds and stop. I would need this to be able to run in the background, so it could not send the keys to the computer as a whole, but only to the Minecraft tab. I am on Windows 10 by the way.
Any help would be appreciated!
Pretty sure you won't be able to, at least not easily let me explain a little bit how all of this works.
Lets start with the hardware and os, the OS has certain functions to read the input you give the computer. This input goes into a "pipe", the OS is reading input, and putting into the pipe, on the other side of the pipe there may be an application running, or it may not. The OS typically manages this (which app to put on the pipe listening) by defining which app/window is active. Apps access this pipe with the API given by the OS, they read the input and decide on it.
The libraries you cited above, change the values of the keyboard and mouse, in other words, they make the OS read other values, not the real ones, then the OS puts them in the "pipe", and are read by the app that is listening on the pipe (the one active). Some apps have their own API's for this, but I would guess Minecraft doesn't. If they don't have an API, what can you do? well, as I said, nothing easy, first of all "hacking" the app, in other words change it to listen to some other input/output rather than the one given by the OS, (this would be you making your own API). The other one would be you changing the OS, which would also be extremely hard, but maybe a tiny bitty easier. It also depends on your OS, I think Microsoft does offer input injection api's
So, simple options, first, run a VM with a GUI and use pywinauto, pyautogui, etc. The other option would be if you can run it in the browser, do so, and use something like Selenium to automate the input.
Quick note, why does selenium works and the browser can read input in the background? Easy, it's not, it just executes the code it would execute if it would have read the input! javascript, cool isn't
With ahk you can do this with Python+AutoHotkey
pip install ahk
pip install "ahk[binary]"
from ahk import AHK
from ahk.window import Window
ahk = AHK()
win = Window.from_pid(ahk, pid='20366')
win.send('abc') # send keys directly to the window
Note that some programs may simply ignore inputs when they are not in focus. However, you can test this works in general even when not in focus by testing with a program like notepad
Full disclosure: I author the ahk library.

Execute a keybind on a different application from python script

It's kind of hard to explain. Maybe the result is out there but I couldn't find it.
Simply put; I would like to run hotkeys on a program running on my desktop (Windows) via Python.
I have a 3rd party program that I have assigned certain hotkeys/keybindings to. For example when ctrl+Fn5 keys are pressed a certain command executes on that program.
What I want to do via Python scripts is to execute the mentioned hotkey (like ctrl+Fn5) on that program. (as if that program had focus on it and those keys were pressed)
I have been trying to do it via win32com.client. But the program itself doesn't allow that feature directly via its libraries. I also tried pywinauto but again it doesn't provide the libraries needed (tried analyzing it with other tools like swapy).
I have used catching hotkeys on python before. But they were for the Python application itself.
for example:
def keyPressEvent(self, e):
if e.modifiers() & Qt.ControlModifier and e.modifiers() & Qt.ShiftModifier and e.key() == Qt.Key_V:
# do somthing
What I need is to execute the hotkeys with the focus on the other program.
I looked into the os module to see if there was anything there that could help me but couldn't find anything.
Using pywinauto modules i got it to work. The trick was getting the focus on the program itself.
from pywinauto.application import Application
from pywinauto.keyboard import SendKeys
app = Application().connect(path='path_to_programs_exe_file')
app_dialog = app.top_window()
app_dialog.maximize()
app_dialog.set_focus()
SendKeys('^{F5}')

Single-module non-blocking Keypress Detection in Python

TL;DR, I'm trying to make a python-only single-module platform-nonspecific non-blocking keypress detector that works in IDLE.
Good luck.
So say I'm running a loop, in IDLE, for an arbitrary amount of time. I want a way to get user input without blocking the loop, on any system I want.
Example:
import keyboard #(is one module in same directory)(Mac, Windows, Linux, who knows?)
teststring = ''
while True:
if keyboard.isDown('a'):
teststring += 'a'
if keyboard.isDown('enter'):
if 'a' in testring:
break
... (neural network or whatever continues)
To put it a different way, I'm trying to make a universal event listener that works in IDLE. If one already exists, do let me know, but I have done some research and none work in one easy-to-use module.
Note:
You don't have to write this, I just want to know what pre-installed Python modules you would use to do this and a general idea of how to go about it.

Recording keyboard input to pseudoterminal

I'm trying to record the keyboard input to a pseudoterminal in python using the pty module in python's standard library. I'm having some difficulty capturing only the keyboard input. While I can easily record the stdout using the callback listed here (in the module documentation), I can't figure out how to get the keyboard input. Should I be using something like termios in conjunction with pty?
If this is possible in another language like C, please also tell!

Simulating Key Press event using Python for Linux

I am writing a script to automate running a particular model. When the model fails, it waits for a user input (Enter key). I can detect when the model has failed, but I am not able to use python (on linux) to simulate a key press event. Windows has the SendKeys library to do this but I was wondering if there is a similar library for python on linux.
Thanks!
Have a look at this https://github.com/SavinaRoja/PyUserInput
its cross-platform control for mouse and keyboard in python
Keyboard control works on X11(linux) and Windows systems. But no mac support(when i wrote this answer).
from pykeyboard import PyKeyboard
k = PyKeyboard()
# To Create an Alt+Tab combo
k.press_key(k.alt_key)
k.tap_key(k.tab_key)
k.release_key(k.alt_key)
A more low-level approach would be to create an uinput device from which you would then inject input events into the linux input subsystem. Consider the following libraries:
python-uinput
evdev
Example of sending <enter> with the latter:
from evdev import uinput, ecodes as e
with uinput.UInput() as ui:
ui.write(e.EV_KEY, e.KEY_ENTER, 1)
ui.write(e.EV_KEY, e.KEY_ENTER, 0)
ui.syn()
If the "model" is running graphically (with the X window system), the already-suggested xsendkey is a possibility, or xsendkeycode. If it's running textually (in a terminal window), then pexpect.
I recommend PyAutoGui. It's ridiculously simple to use, it's cross-platform and it's for Python 3 and 2.
In the linked page are listed the dependences and some code examples.
http://people.csail.mit.edu/adonovan/hacks/xsendkey.html
As many of the solutions I have found in this and in another well ranked SO response were either deprecated (PyUserInput) or using evdev, which failed (UInputError: "/dev/uinput" cannot be opened for writing) the simplest solution for me using Linux was pynput. One example directly from their docs:
from pynput.keyboard import Key, Controller
keyboard = Controller()
# Press and release space
keyboard.press(Key.space)
keyboard.release(Key.space)
# Type a lower case A; this will work even if no key on the
# physical keyboard is labelled 'A'
keyboard.press('a')
keyboard.release('a')
# Type two upper case As
keyboard.press('A')
keyboard.release('A')
with keyboard.pressed(Key.shift):
keyboard.press('a')
keyboard.release('a')
# Type 'Hello World' using the shortcut type method
keyboard.type('Hello World')
It worked like a charm!

Categories