1

I am writing a script intended to be used by members of a project team. As part of the script, I am launching a 3rd party proprietary application run through Citrix. I am going to use the script mostly to send keys to this application, but the first step once it launches is for the user to log in.

Because I would like the user to log in while the script is running, rather than asking for user/pass from some kind of GUI input earlier, and because the time it takes Citrix to launch varies, I would like to include some kind of logic that detects when the user has logged in and then resume the script from there, rather than including an obnoxiously long implicit wait or risking the script timing out.

Is there a way to detect user keystrokes using win32com.client (or to detect a change in state of the application itself)? See below for the relevant code to launch the app:

import win32com.client
shell = win32com.client.Dispatch("WScript.Shell")
shell.Run('C:\Citrix\[rest of path])

EDIT: Per Vasily's suggestion in the comments below, I attempted to adapt the "hook and listen" code to my scenario, but was unsuccessful. When I launch my file, I don't even get an exception message in my terminal, I get a Windows pop-up that says Python encountered a problem and needs to quit.

This is how I adapted it:

#[omitting import lines for brevity]
def on_timer():
    """Callback by timer out"""
    win32api.PostThreadMessage(main_thread_id, win32con.WM_QUIT, 0, 0);


def on_event(args):
    """Callback for keyboard and mouse events"""
    if isinstance(args, KeyboardEvent):
        for i in range(1,100):
            time.sleep(1)
            if args.pressed_key == 'Lcontrol':
                break

def init():
    hk = Hook()
    hk.handler = on_event
    main_thread_id = win32api.GetCurrentThreadId()
    t = Timer(55.0, on_timer)  # Quit after 55 seconds
    t.start()
    hk.hook(keyboard=True, mouse=True)

At the point when the 3rd party Citrix app begins to launch in my main script, I call hookandlisten.init().

As a reminder, my goal is to wait until the user sends a certain keystroke (here I chose Control) before proceeding with the rest of the main script.

5
  • Example: hook_and_listen.py. Commented Apr 26, 2018 at 5:58
  • This looks like it should do the trick! I'll test this out. Can this also be used to trigger a keyboard event (i.e. not just send a keystroke)? Commented Apr 26, 2018 at 14:12
  • Do you mean key hold down and then key release after some other actions? It's possible, but need more detailed description to provide an example or link to the right docs page. Commented Apr 26, 2018 at 17:47
  • It looks like Keyboard did the trick (pypi.org/project/keyboard). One thing I'm still struggling with the above module is it seems to be listening for an action and then performing a specified action, but what I can't seem to get it to do is function as a "Wait" -- that is, once it hears an "Enter" key pressed, continue with the rest of my script, but to do nothing unless or until that key is pressed. Commented Apr 27, 2018 at 19:55
  • @VasilyRyabov I took a stab at modifying that module to match my scenario (see edited post), but was unsuccessful. Where am I going wrong? Commented May 2, 2018 at 19:27

1 Answer 1

2

Solved this by eliminating the timer and unhooking the keyboard upon the correct keystroke:

import win32api
import win32con
from pywinauto.win32_hooks import Hook
from pywinauto.win32_hooks import KeyboardEvent
from pywinauto.win32_hooks import MouseEvent


def on_event(args):

    """Callback for keyboard and mouse events"""
    if isinstance(args, KeyboardEvent):
        if args.current_key == 'Lcontrol' and args.event_type == 'key down':
            print("Success")
            hk.unhook_keyboard()
            return

def init():
    hk.handler = on_event
    hk.hook(keyboard=True, mouse=False)

hk = Hook()
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.