I'm automating some common GUI tasks I have to do in an application, and I'm using a Python program and SendKeys to do it. So far I've had to activate the application I'm sending keys to (since SendKeys just sends the keystrokes to the active window), but I'd like to be able to send keystrokes to an application in the background. Is there a way to do that, or am I dreaming an impossible dream?
Thanks for your help.
pywinauto is another MS-only GUI automation tool, this one written in Python.
SendKeys is a Python module for Windows that can send one or more keystrokes or keystroke combinations to the active window.
If you need to do some automated work in the background, make another user/session and do it in that.
However if you must do something of this like on windows, I always reach for autoit.
It's M$ only and perfectly suited to automating tasks on that OS.
This is a frequent question in the autohotkey.com forums. Search under
"sending commands to controls". Basically, if you have the control ID, then it doesn't need to be visible in order to operate on it. There're more details on the forums.
good luck!
Related
I'm trying to implement numpad in PyQt5 and Windows 10. There are buttons 1, 2, ... 9, enter
I'd like to implement the following event:
When user clicks for example on button 1, the character '1' will be sent to background application (for example notepad).
I have done simple GUI. I only need to implement this event. What libraries, functions can I use to this purpose?
You should research how Inter-process communication works and APIs.
You did not specify which Operating System you target, each one has its own ways to do it.
You mention "sending characters to notepad" but which application do you plan to communicate with ? Because working with any application may be a very difficult problem.
For Notepad I found this question that uses the Windows API to communicate, but it was relatively easy because the source language was C# (which is well-integrated with Windows). According to this other question you should use PyWin32 to do that in Python.
But if you plan your NumPad application to work with many other applications, you should look how other Input sofwares work. It may have clues how to do it.
As the title explain, i'm trying to use the terminal to send commands as keystrokes to a GUI application that's minimized.
There is a lot of similar questions here on Stack with some great answers, but i'm having, mainly, three problems with the solutions i saw: Most of the solutions need the automated application to be the active one. Or, i can't normally use my keyboard while the script/process is running. Or worse, the solution works only on Windows OS.
I need what this person asked 2 months ago: Send keystrokes to a specific window (in background), but do something else in the meantime
But i want it on Linux.
I'm using Kubuntu 18.10, if that helps.
xdotool was close, but i couldn't quite get it to send the commands to a specific window or PID. It also uses "my keyboard", so i can't, for example, write an essay/code/browse online while xdotool is running. Pexpect also have this last problem.
AutoHotKey looks like it would work, but it's only for Windows and i'm trying to not use Wine. Same with pywin32.
keyboard (https://github.com/boppreh/keyboard) seems nice, but it can't send a command to a specific application. Same with PyAutoGUI.
I selected the Python tag because most of the solutions i saw use Python, but i'm open to any language.
Use a nested X server to input keystrokes without changing focus or keyboard grab.
Proof of concept:
Xephyr -resizeable :13
export DISPLAY=:13
xterm
xdotool type rhabarber
The Xephyr nested X server is started and will listen on local X socket 13 (whereas :0 typically identifies the currently running X server, but when multiple sessions are ran concurrently, it could be higher).
Then we set DISPLAY environment variable to :13, so any X application we start will connect to Xephyr; xterm is our target application here. Using xdotool or any other tool we can send keystrokes.
As the target X server is identified through $DISPLAY, applications can be started or input events triggered from elsewhere as well. If needed, you might also run a lightweight window manager within Xephyr, e.g. to 'maximize' the application so that it fills the whole Xephyr window.
I am making application that controls a browser with SendKeys. But as SendKeys get the full control over the keyboard, I want to run this app under the different user. This way I will be working, the application will do what it have to do, and we will not make problems for each other).
The simplest code is
import time
import SendKeys
time.sleep(10)
SendKeys.SendKeys('hello')
I run it, focus on the field where I want to insert my text "hello", and wait. If I don't change the user, all is done as expected.
But when I run it, change the user and return after 10 seconds, I see that SendKeys sent nothing to the program.
How to send keystrokes to the program under the different user?
(I was trying to do the same with pywinauto, but the result was almost the same - all is good if I don't change the user, and error if I change it. So I thought that it is much simplier to resolve this problem with only SendKeys).
Just to summarize our discussion in comments and in the chat. Your wishes are very wide. I'm just trying to show you some directions to learn.
If you want to use SendKeys/TypeKeys/ClickInput methods (working as a real user), you need to run your automation script in the remote session, not locally. This is explained in details in my other answer: SetCursorPos fail with "the parameter is incorrect" after rdp session terminated.
If you want to run the automation on the same machine silently (in minimized state), there is an example for dealing with hidden windows: Python - Control window with pywinauto while the window is minimized or hidden. Just minimize the window and use silent methods (almost all except ClickInput and TypeKeys).
Feel free to ask more detailed questions about pywinauto and GUI automation.
I am very much concerned about my productivity all the time. I have recently come across this beautiful chrome extension Limitless
But this is only measuring what i'm doing within the chrome application. As I work most of the time with pdfs, videos etc, I want to develop similar application for linux(ubuntu) desktop enviroment.
Basically I want the script to run continuously as long as the workstation is on.
It should be able to know what I'm currently looking at (for eg a pdf file or a lecture video in vlc) and get the name of the respective file, start time, end times etc and finally post to db.
It is better if it could know if the system is idle or at sleep.
I don't have slightest clue at bash scripting. so my questions is could this task be accomplished with python.
What I've tried?
I started with a search in google "get current application python", "current window title python" etc etc and really surprised to see absurd results.
Please give me pointers on this.
I think you are asking for vocabulary. So I give you what I know.
You are using Ubuntu so your Window Manager may be Gnome.
The window manager knows which window has the focus.
So maybe you want to find out which window has the focus and you want to map it to the Process that opened the window.
What you need to focus on is is module for Python or a Python Binding for the window manager. This module is likely to also be able to control the windows.
The window manager is started with startx.
You could try to call a command line tool and catch the results
How do get the process list on command line:
https://stackoverflow.com/questions/53489/how-do-you-list-all-processes-on-the-command-line-in-windows
And how to call a tool with python:
Python subprocess.call and subprocess.Popen stdout
[edit] Repeating the call in Intervals and counting the intervals a process were running gives you a good estimation of running time of a process...
[edit2] As GreenAsJade said, you search a way to find out which windows has the focus.
See How do I detect the currently focused application?
How can I detect, or be notified, when windows is logging out in python?
Edit:
Martin v. Löwis' answer is good, and works for a full logout but it does not work for a 'fast user switching' event like pressing win+L which is what I really need it for.
Edit: im not using a gui this is running as a service
You can detect fast user switching events using the Terminal Services API, which you can access from Python using the win32ts module from pywin32. In a GUI application, call WTSRegisterSessionNotification to receive notification messages, WTSUnRegisterSessionNotification to stop receiving notifications, and handle the WM_WTSSESSION_CHANGE message in your window procedure.
If you're writing a Windows service in Python, use the RegisterServiceCtrlHandlerEx function to detect fast user switching events. This is available in the pywin32 library as the RegisterServiceCtrlHandler function in the servicemanager module. In your handler function, look for the SERVICE_CONTROL_SESSIONCHANGE notification. See also the WM_WTSSESSION_CHANGE documentation for details of the specific notification codes.
There's some more detail in this thread from the python-win32 mailing list, which may be useful.
I hope this helps!
In a console application, you can use win32api.SetConsoleCtrlHandler and look for CTRL_LOGOFF_EVENT. In a GUI application, you need a window open and wait for the WM_QUERYENDSESSION message. How precisely that works (and if it works at all) depends on your GUI library.