Bottom Page

Thread Rating:
  • 2 Vote(s) - 2.5 Average
  • 1
  • 2
  • 3
  • 4
  • 5
 pywinauto timings timout error
I switch between several keyboard layouts and have made super primitive scripts with pywinauto to TAB and ENTER until the desired layout is added or removed, but it's not very reliable and i want to learn how to use pywinauto more intimately so i'm making ones that flex more pywinauto muscles.

My pywinauto install passes the self tests I've found, for instance i have no problem running:

from pywinauto.application import Application
# Run a target application
app = Application().start("notepad.exe")
# Select a menu item
app.UntitledNotepad.menu_select("Help->About Notepad")
# Click on a button
# Type a text string
app.UntitledNotepad.Edit.type_keys("pywinauto Works!", with_spaces = True)
what i'm trying to do is pull up the intl.cpl window, which is the Region window, then select the blue text 'Language preferences'(i'm on windows 10), then select the proper layout to add or delete, then save and close. like i said i'm able to do this with a bunch of tabs and enters through pywinauto.keyboard.SendKeys but it's not very reliable.

I've been using SWAPY and Inspect.exe to make sure I'm using the proper class names and I'm testing each step of the way so I know I'm building it right, and I've already hit a snag.

Here's my code so far:

from pywinauto.application import Application

app = Application().Start(cmd_line=u'control intl.cpl')
window = app.Region
syslink = window.SysLink

Whether i try it in the interpreter or from a script i get a timout error,

2016-12-03 04:32:37,819 INFO: Imported existing <module 'comtypes.gen' from 'C:\\Python35\\lib\\site-packages\\comtypes\\gen\\'>
2016-12-03 04:32:37,824 INFO: Using writeable comtypes cache directory: 'C:\Python35\lib\site-packages\comtypes\gen'
Traceback (most recent call last):
  File "", line 5, in <module>
  File "C:\Python35\lib\site-packages\pywinauto\", line 486, in wait
    wait_until(timeout, retry_interval, lambda: self.__check_all_conditions(check_method_names))
  File "C:\Python35\lib\site-packages\pywinauto\", line 343, in wait_until
    raise err
pywinauto.timings.TimeoutError: timed out
So it seems like I'm getting the timeout error because it's waiting for the window to be 'ready', but even when i change this to 'exists' i get the same error. it's as if i'm not connecting to the window properly in the first place. if i take the wait line out and try importing time and using time.sleep(0.5) i get a timout error from the next line requiring a wait signal. if i take everything out after and leave in the app.Kill_() it doesn't exit and the script ends without errors, so I'm pretty sure I'm just not connected to the window because I started it with cmd.

Do I need to use application.connect on the window somehow? intl.cpl isn't an application so do i need to use findwindows or something? I've been fiddling with it for a couple days and any help would be greatly appreciated.
bumpin. it seemed like pywinauto is a good way to go to automate windows stuff. better than having to learn the monster that is the windows api imo. is this not a common module or something?
I had a play around with it but couldn't get the handler for the region window, normally it's not so difficult using pywinauto but some gui types can be a pain. You will probably have more luck asking the developers how to handle such a troublesome gui.
Well I made some progress. I had to connect to the Region window after bringing it up.

For myself and for anyone else that stumbles upon this thread, here's the working code with comments:

note: this code is for removing the second keyboard layout on Windows 10, in this case removing the Dvorak keyboard layout. Feel free to modify this to add/remove any layouts you want, you'll just have to fiddle with the while loops for how many tabs and down arrows should be used.
from pywinauto.keyboard import SendKeys #imports SendKeys method to be able to send keystrokes
from pywinauto.application import Application #imports Application method for starting/connecting to windows
import time #imports time so time.sleep can be used

count = 0 #an int to count the number of times a keystroke is hit

Application().Start(cmd_line=u'control intl.cpl') #starts the Region window by issuing the cmd command 'control intl.cpl'
app = Application().connect(title_re="Region") #connects the variable app to the now open window with the title of Region
dlg = app.Region #The line above and this line could be joined to read,
#dlg = Application().connect(title_re="Region").Region
dlg.SystemLink2.Click() #clicks on the bluetext "Language preferences"
time.sleep(0.4) #pauses to let the new window come up

app2 = Application().connect(title_re="Language") #connects app2 to the now open Language window
dlg2 = app2.Language #same as before, both the line before and this one could written as one, 
#dlg2 = Application().connect(title_re="Language").Language
dlg2.SysListView32.Click(double=True) #double clicks on the big language bar at the top of the list

while count < 4:
  SendKeys('{VK_TAB}') #sends TAB keystroke 4 times, until remove is highlighted for the 2nd language(in this case dvorak)
  time.sleep(0.1) #probably unnecessary but this keeps the computer from being overwhelmed with keystrokes and skipping one
  count += 1 #increases the counter

SendKeys('{VK_RETURN}')#Hits 'remove' for Dvorak here the save button

SendKeys('%{F4}')#exits Language window
SendKeys('%{F4}')#exits Region window
I had to settle for using some tabs and enters like in my first primitive script, because there were so many control identifiers to pour over for the 'Language' window and I couldn't find one for the 'remove' button after some searching. SWAPY and Inspect.exe only reference to it by name. I think there's a way to search for objects in windows by name alone with pywinauto, but i have yet to figure that out. That would probably eliminate the need for tabs and enters all together.

I'll make sure to follow up on this thread when i figure that out. This is definitely a big step from relying on a bunch of while loops of TAB keystrokes. These new scripts seem much more reliable from the little testing I've done.

I should also put this here, this was what i used to export the output of the PrintControlIdentifiers() method to a text file, so that I didn't have to bother pouring over it in the shell, which couldn't display it all at once anyway(due to a low text output buffer) at least i think it's called 'buffer'.

#redirecting stdout temporarily to spit out to a file
import io
import contextlib

f = io.StringIO()

with open('tempSpit.txt', 'w') as f:
  with contextlib.redirect_stdout(f):
The above code spits the result of dlg.PrintControlIdentifiers() to tempSpit.txt by temporarily hijacking stdout.
Obviously dlg needs to be connected to a window before this will work properly.
With some windows the text file may be only written half way before crashing due to an encoding error. I'm sure there is a way to force this script to use UTF-8 or Unicode, but i don't know how at this time.

Anyway hope that helps anyone that's had similar questions!
nilamo and Yoriz like this post
Well done for figuring out how to get it working and thanks for posting your solution.
nilamo likes this post

Top Page

Possibly Related Threads...
Thread Author Replies Views Last Post
  Checking the presence of label using pywinauto module Malt 0 199 Jul-26-2019, 09:06 AM
Last Post: Malt
  [PyWinAuto] Please help me with Typekeys () mattroi261192 2 422 Apr-23-2019, 01:55 AM
Last Post: mattroi261192
  Not able to convert PYWINAUTO module automation in exe file Utkarsh29 0 366 Mar-19-2019, 09:39 PM
Last Post: Utkarsh29
  pywinauto problems vnc 3 3,222 Apr-13-2017, 11:21 AM
Last Post: vnc

Forum Jump:

Users browsing this thread: 1 Guest(s)