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!
Related
I found a solution for this online but just don't like it, see following code:
try:
while True:
# code here
except KeyboardInterrupt:
break
The continuous is to be run in an IIoT device that has as OS Linux but with limited memory and capabilities.
I could just do
pip install
keyboard to use any other characters than ctrl + c,
let said "s" for stop but the package may not install in the device. I tested some code with curses to not avail. Please advice.
It might be possible that you have no other choice that get the keyboard lib.
the other but very complicated solution is to use the serial
get the serial port your keyboard is connected to the IOT device.
configure it with the right params
and listen to messages.
If you collect any type of message, it means you pressed a key
Here is the doc for pyserial
You can also try to compile the keyboard library with Cython to optimise space
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
I'm sending keyboard signals to the OS (Windows) via python. The problem is the specific application (Project 64, Nintendo 64 emulator) is not receiving the signals, I'm not sure why. The keys are registered in Word and my browser for example.
shell = win32com.client.Dispatch("WScript.Shell")
ser=serial.Serial('com10',115200)
while 1:
datain=ser.read(1)
if datain=='':
continue
datain_int=int(binascii.hexlify(datain), 16)
datain_bin=bin(datain_int)
if datain_int==0:
continue
print(datain_int)
if datain_int==128:
shell.SendKeys("a")
Since other applications are receiving your keystrokes it is entirely possible that the application, being an emulator, is scanning the keyboard directly rather than having keystrokes passed from the operating system.
If this is the case you would probably be better off downloading the source code and patching it to use input from the serial port directly. You an also have a look at the source code to see how it is receiving the keyboard events.
There is some way to get the device path of a mouse and keyboard using Xlib based in a looping with XNextEvent? I need to know what /dev/input/event* generates a event specific like mouse press and keyboard key F1 press.
I'm using evdev for input devices in Xorg, I searched documentation and cannot find a way.
I accept too suggestion of some app that I can use to identify input device based in events like mouse press and keyboard press.
Thanks.
Edit: If there is a way to make this using another lib, preferable one with bindings for python, please let me know.
I realize that Xlib do not have a method to get the file descriptor of the input devices, so I figured out another way to resolve this case, is not ready yet, but apparently is the best way to follow, just posting here for someone with the same problem.
I'm using the module python-evdev (installed with pip in ubuntu), with this module I can monitor the devices is /dev/input/event*, so I just need to start a thread for each device that I previous identified which is a mouse or keyboard (using the module evdev and checking if device have "capabilities(verbose=True)" with event codes like ecodes.KEY_F1 and ecodes.BTN_MOUSE), and when a event occur, write to a shared variable, that I should monitor.
For the graphic interface running in Xorg, without Windows Managers, I using python-glade2, works like a charm, I run a Xorg with python-glade2 app using xinit.
I'm writing an command-line application which listens for Control key release events in X Windows and alerts another process when it detects them.
Being new to GNU/Linux, I'd prefer avoiding to fumble with GCC and therefore I'm looking for a scripting-based solution. Since I know a bit of Python, it seemed natural to go for a Python-based solution, and after scavenging the Internet for examples and reading Python Xlib docs, I've put together this programs which works, but with a caveat: it traps events instead of just listening for them (I mean such events are not passed anymore to the application which they were directed to in the first place).
I've tracked down Control key codes by running "xev". Since I've remapped my modifier keys, on your system they may be different.
To keep things simple, I've left out the code which deals with the external process.
Thank you for your help.
Software:
Python 2.7.2
Python Xlib 0.15 RC1
Perl v5.10.1
Debian GNU/Linux version: 6.0.3
Kernel version: Linux debian 2.6.32-5-686
EDIT: What I can't figure out is that keyboard events do not get trapped unless they are processed (in my programs, this means the line 'print "KeyRelease"' gets executed). Since in my code I don't call any method either on Xlib or on the event object, I don't understand where the difference in processing lies.
EDIT2: Suggestions about alternative solutions besides using Xlib are also welcome.
EDIT3: I know Perl too, and suggestions about Perl libraries which could help are welcome too, as long as they don't require recent versions of system libraries, since Debian notoriously lags behind when it comes to packages available in its repositories, and compiling and installing last versions of libraries can be difficult if they have many dependencies (I've tried installing PyGTK, but gave up after failing to reference an up-to-date GLib I had installed).
#!/usr/bin/env python
from Xlib.display import Display
from Xlib import X
Control_R = 64 # Keycode for right Control.
Control_L = 108 # Keycode for left Control.
keycodes = [Control_R, Control_L] # Keycodes we are listening for.
# Handle X events.
def handle_event(event):
# Let us know whether this event is about a Key Release of
# one of the key we are interest in.
if event.type == X.KeyRelease:
keycode = event.detail
if keycode in keycodes:
print "KeyRelease"
# Objects needed to call Xlib.
display = Display()
root = display.screen().root
# Tell the X server we want to catch KeyRelease events.
root.change_attributes(event_mask = X.KeyReleaseMask)
# Grab those keys.
for keycode in keycodes:
root.grab_key(keycode, X.AnyModifier, 1, X.GrabModeAsync, X.GrabModeAsync)
# Event loop.
while 1:
event = root.display.next_event()
handle_event(event)
Thanks to the pykeylogger library mentioned by Croad Langshan, and to the helpful example code provided by Tim Alexander, the author of such library, I've been able to change my program to:
#!/usr/bin/env python
from pyxhook import HookManager
watched_keys = ["Control_R", "Control_L"]
def handle_event (event):
if event.Key in watched_keys:
print "KeyRelease"
hm = HookManager()
hm.HookKeyboard()
hm.KeyUp = handle_event
hm.start()
This program accomplishes my goal without any issue. You can read the fields of the "event" object for further information about the event (see source code of "pyxhook.py").
You need to use the XRecord extension. It can be used with pyxlib (pykeylogger mentioned in the other answer uses this), or by wrapping libX11 and libXtst via ctypes (as I did in synaptiks).
Note however, that programming with xrecord (and to some degree also with XLib in general) is somehwat hard, because the API is badly documented, and quite baroque and counter-intuitive.
Presumably this project must have code that solves that problem:
http://sourceforge.net/apps/mediawiki/pykeylogger/index.php?title=Main_Page
Note that the XRecord extension continues to be broken in a few distributions. The reason I hadn't gone back and updated that library for a while was because it was broken in Ubuntu for multiple releases. There's a way to do it as well with an XInput overlay, (I'm told) but I never pursued that because I didn't want to deal with an overlay rather than hooking the X events directly.
Comment back if there's any issues with using the code in the pyxhook lib, I tried to make it as simple/robust as possible, but I may have missed stuff when putting it together. It was a while ago.