Detect windows logout in Python - python

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.

Related

Send keystrokes to non-active GUI application without occupying the keyboard

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.

Python - control application started by the different user in Windows

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.

Sending notifications with GObjects

There seems to be a distinct lack of documentation of the GObjects module for python at the moment, so maybe somebody can help me.
I am making an application which occasionally will have to notify the user that an event has occurred. I have found about using from gi.repository import Notify and the relating classes from using a short snippet for skype notifications and the C documentation, but it seems to not close when I call Notify.uninit. The program closes, but the little notification window thing stays put and has to be closed by right clicking on it and selecting "Remove". So, I am wondering if there is perhaps another way like if there was something similar to how in Mac OS the application icon shakes/bounces when something happens or in Windows the application icon glowing a different color?
I like the Gnome 3 notification system with the message stack and such, but since I can't seem to get it to disappear when my application exits I don't really want to use it (unless someone knows how to properly do this...it may be that I forgot to set a timeout, but that still doesn't make sense as to why I can't just make the notification spot disappear).
Calling Notify.uninit is not supposed to make the notifications disappear, it only tells libnotify that it will no longer be needed for your application. To make notifications disappear, you have to close them explicitly like in the following example:
import time
from gi.repository import Notify
Notify.init('myapp')
# optionally set an icon as the last argument
n = Notify.Notification.new('summary text', 'body text', "dialog-information")
n.show()
# do whatever your application is doing
time.sleep(10)
n.close()
Notify.uninit()

Altering "Send To" on Windows with Python

I need to redirect the "Send To Mail Recipient" menu in Microsoft Office (primarily Word and Excel) to send the document using a web client email. I need to do the same thing with the context menu that appears when right-clicking a file (i.e. Send To -> Mail Recipient).
I'd like to catch these events using Python, probably via PyWin32 via COM or ctypes. Does anyone know how to do this sort of thing? I'm using Windows XP and Python 2.6. Thanks!
the only thing I can think of is to use Microsoft Active Accessibility bindings for Python. These give you the ability to monitor events, including window open/close events. I can't think of any other library that has this functionality.
http://www.cs.unc.edu/Research/assist/doc/pyaa/public/pyAA.AA.AccessibleObject-class.html
I won't kid you. This is not a pretty solution, but it can work.
here's another description:
http://web.archive.org/web/20080510165211/mindtrove.info/articles/gui-automation-with-pyaa/

Python Send Keystrokes to Non-Active Application

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!

Categories

Resources