Giter Club home page Giter Club logo

Comments (59)

airelil avatar airelil commented on May 19, 2024 1

Hi @nimuston. I also created a small snippet based on the WPF application from our samples.

from pywinauto.application import Application

# Create Application with UIA backend 
# (requires pywinauto 0.6 or greater)
app = Application(backend="uia")

# Start a WPF sample
app.start(r"apps\WPF_samples\x64\WpfApplication1.exe")

# Just define a window spec for a dialog window
# (no actual search for a dialog is performed at this point)
dlg = app.WpfApplicationSample

# Describe a control with a specific automation id
ctl = dlg.child_window(auto_id="button2")

# Only now we try to find a dialog and a control as they've been
# described by the window specs above. If the whole name resolution
# is succeeded the 'draw_outline' action will be applied to the control
ctl.draw_outline()

# To have constant access to the control without having to run
# through name resolution process again and again we store the found
# wrapper 
# (Notice that pywinauto runs the additional search here to resolve ctl again)
wrp = ctl.wrapper_object()

# Now we have the wrapper at our hands and we can work with our control
wrp.draw_outline("red")
wrp.invoke()

from pywinauto.

nimuston avatar nimuston commented on May 19, 2024 1

i'm still wondering about this error message i got from the invoke() method. It seems that it is waiting a response from the app being tested, because for example in my script i press one button and if i after that do something in the tested app or press "esc" key when the test app is so called active, then my script is completed successfully and no error, but if dont do anything then my script fails and gives this error below.

Traceback (most recent call last):
  File "auto_test1.py", line 77, in <module>
    uia_press()
  File "auto_test1.py", line 70, in uia_press
    dlg.click()
  File "build\bdist.win-amd64\egg\pywinauto\controls\uia_controls.py", line 112, in click
  File "build\bdist.win-amd64\egg\pywinauto\controls\uiawrapper.py", line 409, in invoke
_ctypes.COMError: (-2147220991, 'An event was unable to invoke any of the subscribers', (None, None, None, 0, None))
button = window.child_window(auto_id='_buttonName_1')
dlg = button.wrapper_object()
dlg.invoke()

or

button = window.child_window(auto_id='_buttonName_1')
dlg.click()

result is the same

from pywinauto.

nimuston avatar nimuston commented on May 19, 2024 1

I found this small app from internet and with that I'm able to reproduce my problem. For some reason I'm not able to upload it here so you can download it from this website:

http://www.ittutorialswithexample.com/2015/01/simple-windows-form-login-application-in-csharp.html

below code that I'm using:


from pywinauto.application import Application

app = Application(backend='uia')
app.Start(r'D:\LoginApplication.exe')
handle = app.window_(title='Login')
button = handle.child_window(auto_id='btn_Submit')
dlg = button.wrapper_object()
dlg.draw_outline()
dlg.click()

from pywinauto.

airelil avatar airelil commented on May 19, 2024 1

Hi @nimuston, finally I got a chance to look into your demo app. I think your main problem is (at least in the demo) that you got a modal dialog blocking the invoke method. Look at this link for more details. @vasily-v-ryabov, there is an interesting point in the answer by Michael Bernstein, should we add an option to run invoke in a separate thread? Anyway, here the code that works fine for me. I opted out to click_input to get through the modal dialog.

from pywinauto.application import Application

app = Application(backend='uia')
app.start(r"LoginApplication.exe")

# Use a window title to get acccess to the main window
# but we could use app.top_window_() as well
login_dlg = app.Login

# Look around and learn available ID to work with
login_dlg.print_control_identifiers()

# The common way to access controls - just use IDs printed above
login_dlg.Edit0.type_keys("passw")
login_dlg.Edit2.type_keys("user")

# Another option is based on Automation IDs that can be retrieved with Inspect.exe utility
login_dlg.child_window(auto_id="txt_Password").set_text("passw2")
login_dlg.child_window(auto_id="txt_UserName").set_text("user2")

# click() method is based on Invoke pattern but we can't use invoke
# as the app brings in a modal dialog, so we revert to click_input()
# https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/d2a086f5-9774-4fa4-80d2-18ed1a2d0bb6/too-slow-invokepattern-using-uiautomation?forum=windowsaccessibilityandautomation
login_dlg.child_window(auto_id="btn_Submit").click_input()

# Re-print the control identifiers with more sub-levels and
# try to find ID of the popped up modal dialog
login_dlg.print_control_identifiers(depth=4)

# As we found out there is a second modal dialog with an "Ok" button on it
# Now we can just click on it and get to our main "after-login" application screen
login_dlg.Dialog2.OkButton.click()

from pywinauto.

airelil avatar airelil commented on May 19, 2024 1

dlg.invoke()

Why dlg ? What do you try to access ? A control or a window ? If it's a control, at least, give a meaningful name to your variables.
NoPatternInterfaceError means that this cryptic dlg doesn't support Invoke pattern of MS UI
Automation.

I doubt all these wild guesses are going to get us anywhere. Please bring a clean and concise example demonstrating your problem, open a separate issue for this and we'll try to help.

from pywinauto.

GoogleCodeExporter avatar GoogleCodeExporter commented on May 19, 2024
even i had the same issue, how can we automate WPF based applications

Original comment by [email protected] on 29 Feb 2012 at 11:44

from pywinauto.

GoogleCodeExporter avatar GoogleCodeExporter commented on May 19, 2024
i had the same issue,anyone knows how to solve it

Original comment by [email protected] on 8 Jan 2014 at 8:41

from pywinauto.

vasily-v-ryabov avatar vasily-v-ryabov commented on May 19, 2024

Hmm... It seems UIA doesn't support TextPattern for native text controls like a label.
Guy Barker from MS claimed it here. So mixed (native+UIA) approach would be very useful if we were implemented it in pywinauto 0.6.x.

from pywinauto.

vasily-v-ryabov avatar vasily-v-ryabov commented on May 19, 2024

pywinauto 0.6.0 high-priority tasks status

  • 1) Make BaseWrapper abstract class.
  • 2) Create many UIA wrappers for every control type.
    • 2.1) Checkable & button controls like check boxes, radio buttons, buttons, group boxes etc.
    • 2.2) Plain list controls like list boxes and list views.
    • 2.3) ComboBox
    • 2.4) TreeView
    • 2.5) Menu
    • 2.6) Grid
  • 3) Avoid __new__ method duplication in HwndWrapper, UIAWrapper & BaseWrapper.
  • 4) Rewrite __getattr__ to __getattribute__ for new-style classes.
  • 5) Make most of the code PEP-8 complaint. Old native methods should have non-PEP-8 aliases for compatibility reasons.
  • 6) Make backend switching application-specific, not global. Expected result: app = Application(backend="uia").start('WpfApplication1.exe').
    • 6.1) Avoid backend-specific things in BaseWrapper.

from pywinauto.

vasily-v-ryabov avatar vasily-v-ryabov commented on May 19, 2024

Meta class inheritance schema regarding (6.1), (3) and (1):

>>> import abc
>>> class BaseMeta(abc.ABCMeta):
...     @staticmethod
...     @abc.abstractmethod
...     def find_wrapper(element_info):
...         pass
...     
>>> class BaseWrapper(object):
...     __metaclass__ = BaseMeta
...     def __new__(cls, element_info):
...         new_class = cls.FindWrapper(element_info)
...         return object.__new__(new_class)
...     
>>> class HwndMeta(BaseMeta):
...     @staticmethod
...     def find_wrapper(element_info):
...         return HwndWrapper
...     
>>> class HwndWrapper(BaseWrapper):
...     __metaclass__ = HwndMeta
...     

from pywinauto.

airelil avatar airelil commented on May 19, 2024

@vasily-v-ryabov please fix the syntax in your schema. For Python 2.7, It should be:

class BaseMeta(object):
    __metaclass__ = abc.ABCMeta

You can't inherit metclass

from pywinauto.

vasily-v-ryabov avatar vasily-v-ryabov commented on May 19, 2024

It's checked on Py2.6. No syntax errors raised.

from pywinauto.

airelil avatar airelil commented on May 19, 2024

It's not about syntax. You'll get weird error messages when you try instantiate it. See a question on SO: http://stackoverflow.com/questions/31340339/python-error-when-initializing-a-class-derived-from-and-abstract-one

from pywinauto.

funkyHat avatar funkyHat commented on May 19, 2024

@airelil you can't instantiate a metaclass. I don't think that's what's happening here. Subclassing a metaclass is fine.

from pywinauto.

vasily-v-ryabov avatar vasily-v-ryabov commented on May 19, 2024

Yeah, I've found it in abc module help:

Using this decorator requires that the class’s metaclass is ABCMeta or is derived from it. A class that has a metaclass derived from ABCMeta cannot be instantiated unless all of its abstract methods and properties are overridden.

Even the following thing is possible:

@six.add_metaclass(abc.ABCMeta)
class BaseMeta(abc.ABCMeta):
    "Abstract metaclass for Wrapper objects"

    @staticmethod
    @abc.abstractmethod
    def find_wrapper(element):
        raise NotImplementedError()

from pywinauto.

airelil avatar airelil commented on May 19, 2024

Sorry, my bad. Didn't notice it was subclassing for another metaclass.

from pywinauto.

airelil avatar airelil commented on May 19, 2024

Several samples I found at Microsoft. Maybe they could be used for developing UIA wrappers.
TreeView: https://code.msdn.microsoft.com/windowsdesktop/File-system-TreeView-72549a6f
Ribbon controls: https://code.msdn.microsoft.com/windowsdesktop/Ribbon-Controls-Sample-003c390a
DataGrid: https://code.msdn.microsoft.com/windowsdesktop/Il-controllo-DataGrid-in-230577b3
Calculator (requires VS2012): https://code.msdn.microsoft.com/windowsdesktop/MyCalCulator-18767f9b

from pywinauto.

vasily-v-ryabov avatar vasily-v-ryabov commented on May 19, 2024

Control Type Identifiers
Control Pattern Identifiers

from pywinauto.

SravaniAnnepu avatar SravaniAnnepu commented on May 19, 2024

Hi Vasily,
Can you please let me know the expected completion date of pywinauto 0.6.0 for WPF support?

from pywinauto.

vasily-v-ryabov avatar vasily-v-ryabov commented on May 19, 2024

Hi @SravaniAnnepu, we're going to merge UIA branch into master till the end of September. 0.6.0 is planned for October.

from pywinauto.

nimuston avatar nimuston commented on May 19, 2024

Hi, I'm new with test automation and my question might be related to this WPF app support. At the moment i have a problem with identifier's, I'm using autoit V3 inspector tool to find out what are the identifier's in my app what I'm automating and I'm basically using class and instance to click example buttons, but what i really want to use is the control name (internal .NET Framework WinForms name). Because it seems that in some situation my instance number is changing so my tests are failing because of this and this control name seems to always be the same. Is there a possibility to use this control name as identifier in pywinauto? if not now maybe with pywinauto 0.6.0? I added also this picture to clarify my question :D so there you can see in the control tab that the name is button7 and this is what i want to use in my script like this.

ctrl = window[str('button7')]
ctrl.Click()

autoit

from pywinauto.

vasily-v-ryabov avatar vasily-v-ryabov commented on May 19, 2024

Hi @nimuston. It seems your case is WindowsForms application that is partially Win32 API compatible, so pywinauto 0.5.4 is able to use button7 as an identifier. Say app.Calculator.button7.click() should work.

Of course, coming MS UI Automation support is better for WinForms: it can detect more complicated control types. AutomationId of a control is another benefit of UIA. For WinForms AutomationId property is usually a programmatic name of the control like m_buttonSeven (exactly what's declared in the source code of the app).

BTW, Inspect.exe is the best GUI object inspector (it uses UIA mode as well). It can be found in Windows SDK folders (just search in Program Files* folders for Inspect.exe).

from pywinauto.

vasily-v-ryabov avatar vasily-v-ryabov commented on May 19, 2024

Planned release date for 0.6.0 is October, 30. We're in the master branch. So early testing is available downloading master as zip and running python setup.py install.

from pywinauto.

vasily-v-ryabov avatar vasily-v-ryabov commented on May 19, 2024

@nimuston, to be more specific possible identifiers are <control_text> (returned by WindowText() method), <control_text><control_type> (like OKButton), <left_static_text><control_type> (like FileNameEdit) and <control_type><autoincrement_number> (unstable in your case).

But you also can create more detailed window specification to find proper control. Something like that

control_spec = app.Calculator.ChildWindow(title='7', class_name='Button', found_index=0)

# to make sure it's a proper control while debugging in interactive mode
real_ctrl = control_spec.wrapper_object()

control_spec.click()

found_index filters only found controls with the rest of search criteria specified in ChildWindow call. So if number of buttons with specified title or title_re is stable, it might be useful. In some cases only total number of all controls are changing while some specific controls are of the same amount.

from pywinauto.

nimuston avatar nimuston commented on May 19, 2024

hi,

If i'm not mistaken all the identifier's what pywinauto can use, can be printed out with PrintControlIdentifiers() method? and in this list there is no reference to this .net control name.

I sound to me that this AutomationId is the right solution for my problem, like you said
control's are named like m_buttonSeven and this is also the case here. Maybe this calculator example was bit misleading.

How this UI automation support will work in pywinauto 0.6.0? is it so that PrintControlIdentifiers() method will recognize then this control name?

from pywinauto.

airelil avatar airelil commented on May 19, 2024

Basically, any control that you can see with Inspector.exe running in "UIA mode" should be reached with "UIA" backend. UIA backend is activated during creating Application object:
app = pywinauto.application.Application(backend='uia') # needs pywinauto 0.6 or later

from pywinauto.

nimuston avatar nimuston commented on May 19, 2024

so it should work something like this in pywinauto 0.6.0?

import pywinauto
app = pywinauto.application.Application(backend='uia')
app.Start('calc.exe')
app.Calculator.Button1.Click()

in this example button1 value comes from inspect.exe automationID field, but what if automationID is something like "-button1-" how this is handled? should i make variable that contains this value example

button1 = '-button1-'

if this example is totally wrong can you give me example how this should work with automationID?

from pywinauto.

vasily-v-ryabov avatar vasily-v-ryabov commented on May 19, 2024

If control name or AutomationId contains non-alphanumeric symbols, access by item key is possible:

app.Calculator["-button 1-"].Click()

or even more detailed window specification:

app.Calculator.ChildWindow(title_re='^.*7$', class_name='Button').Click()

In the issue #120 I've explained it in more details. Will move to the docs soon.

from pywinauto.

nimuston avatar nimuston commented on May 19, 2024

Hi, Great example thank's for that. it works for me at some level, only problem is that pywinauto 0.6.0rc seems to crash my python interpreter time to time. When i type wpr.invoke( it freezes and then it is not responding anymore. Also when i import pywinauto library i get these info messages from comtypes module

"INFO: Imported existing <module 'comtypes.gen' from c:\python27\lib\site-packages\comtypes-1.1.2-py2.7.egg\comtypes\gen_init_.pyc'>"
"INFO: Using writeable comtypes cache directory: 'C:\python27\lib\sute-packages\comtypes-1.1.2-py2.7.egg\comtypes\gen'

btw is it possible for the real release of pywinauto 0.6.0 to get PrintControlIdentifiers() method to also print out these automationID's if they are available in the target software? it would be really helpful.

Also is the release date october 30 still valid? this is really good library for test automation so great job guys!!

from pywinauto.

vasily-v-ryabov avatar vasily-v-ryabov commented on May 19, 2024

Thank you, @nimuston. We really appreciate your feedback.
Release date is valid. We'll do our best to be on time.

The interpreter freeze problem happens because Python tries to resolve all the attributes to show you an auto-complete list. The default timeout for finding non-existing window/control is up to 5 seconds for 1 attribute. So it may appear as not responding window. Currently I have no idea how to improve it.

print_control_identifiers() should definitely be improved. I'm planning to add something like that for every control: child_window(title="some name", auto_id="m_name", control_type="Button") so that automation engineer could just copy-paste a detailed window specification into his code if necessary.

from pywinauto.

airelil avatar airelil commented on May 19, 2024

@vasily-v-ryabov , I'm not sure if the freeze of wrp.invoke( is because of attempting to find all controls. In my example wrp is a fully fledged wrapper object...

@nimuston, did you try to run a couple of UIA unittests? Just to make sure that your setup is good. This is how you could invoke a bunch of unit tests with a WPF sample:
python pywinauto/unittests/test_uiawrapper.py UIAWrapperTests

from pywinauto.

nimuston avatar nimuston commented on May 19, 2024

what about those comtypes info messages? i installed latest comtypes 1.1.3 library and i got even more info messages and also after that my python script does not work anymore.

what comtypes library i should use with pywinauto?

also it seems that in time to time i get this pywinauto.findwindows.ElementNotFoundError when i run my code.

from pywinauto.application import Application

app = Application(backend='uia')
app.start(r'C:\apps\calculator.exe')
dlg = app.calculator
ctl = dlg.child_window(auto_id='button7')
wrp = ctl.wrapper_object()
wrp.invoke()

and below the error message i got

Traceback (most recent call last):
File "calc.py", line 7, in
wrp = ctl.wrapper_object()
File "build\bdist.win-amd64\egg\pywinauto\application.py", line 238, in wrappe
r_object
File "build\bdist.win-amd64\egg\pywinauto\application.py", line 231, in __reso
lve_control
pywinauto.findwindows.ElementNotFoundError: {'process': 3960, 'best_match': 'cal
culator', 'backend': u'uia'}

from pywinauto.

nimuston avatar nimuston commented on May 19, 2024

@airelil i ran those unittests and it ran 22 tests and seems to be ok

from pywinauto.

airelil avatar airelil commented on May 19, 2024

On my machine I use comtypes-1.1.2 Works for py27 and py34. Maybe you need to clean the generated caches in 'comtypes-1.1.2-py2.7.egg\comtypes\gen' folder manually.

Regarding your error, it doesn't look as the output for the specified script. ElementNotFoundError is raised when the lookup fails to match any control to the specified criteria. But for you script it should include the "auto_id" filter.
When I fail my example intentionally:

ctl = dlg.child_window(auto_id="button2111")  # <- Non-existing automation id
wrp = ctl.wrapper_object()
wrp.invoke()

I get a slightly different error with details of filters (including auto_id):

    230         except TimeoutError as e:
--> 231             raise e.original_exception
    232
    233         return ctrl

ElementNotFoundError: {'auto_id': 'button2111', 'top_level_only': False, 'parent': <pywinauto.uia_element_
tInfo object at 0x0000000005105DA0>, 'backend': u'uia'}

from pywinauto.

vasily-v-ryabov avatar vasily-v-ryabov commented on May 19, 2024

Info messages from comtypes can be suppressed by setting appropriate level for logging module when loading UIAutomationCore.dll. Will look into that later.

One more restriction on comtypes usage is that it doesn't load some stuff like IUIAutomationRegistrar for 3rd party properties and custom controls.

from pywinauto.

nimuston avatar nimuston commented on May 19, 2024

i also got this error message from invoke() method

File "build\bdist.win-amd64\egg\pywinauto\controls\uiawrapper.py", line 409, in invoke
_ctypes.COMError: (-2147220991, 'An event was unable to invoke any of the subscribers', (None, None, None, 0, None))

from pywinauto.

nimuston avatar nimuston commented on May 19, 2024

i got the latest pywinauto from the master branch and i'm not able to install it if i don't install comtypes 1.1.3 first. Well it will download it from the web if its possible, but in my development machine i needed to install comtypes 1.1.3 manually before pywinauto was able to complete installation

from pywinauto.

vasily-v-ryabov avatar vasily-v-ryabov commented on May 19, 2024

File "build\bdist.win-amd64\egg\pywinauto\controls\uiawrapper.py", line 409, in invoke
_ctypes.COMError: (-2147220991, 'An event was unable to invoke any of the subscribers', (None, None, None, 0, None))

It usually happens when the element already doesn't exist. Need to raise more readable exception. Thanks.

i got the latest pywinauto from the master branch and i'm not able to install it if i don't install comtypes 1.1.3 first.

What is the output of python setup.py install when comtypes not installed?

from pywinauto.

nimuston avatar nimuston commented on May 19, 2024

File "build\bdist.win-amd64\egg\pywinauto\controls\uiawrapper.py", line 409, in invoke
_ctypes.COMError: (-2147220991, 'An event was unable to invoke any of the subscribers', (None, None, None, 0, None))

this error is bit strange because the script i have does everything it should and after that gives this error. Well only thing my script does at the moment is that it presses one button only, it also takes long time to complete the action.

for the comtypes problem, it seems that the installer is looking for comtypes 1.1.3. Also i need to install following packages:

setuptools_scm-1.0.0-py2.py3-none-any.whl
pypiwin32-219-cp27-none-win_amd64.whl
six-1.10.0-py2.py3-none-any.whl

Installed c:\python27\lib\site-packages\pywinauto-0.6.0rc1-py2.7.egg
Processing dependencies for pywinauto==0.6.0rc1
Searching for comtypes==1.1.3
Best match: comtypes 1.1.3
Processing comtypes-1.1.3-py2.7.egg
comtypes 1.1.3 is already the active version in easy-install.pth
Installing clear_comtypes_cache.py script to C:\python27\Scripts

Using c:\python27\lib\site-packages\comtypes-1.1.3-py2.7.egg
Searching for pypiwin32==219
Best match: pypiwin32 219
Adding pypiwin32 219 to easy-install.pth file

Using c:\python27\lib\site-packages
Searching for six==1.10.0
Best match: six 1.10.0
Adding six 1.10.0 to easy-install.pth file

Using c:\python27\lib\site-packages
Finished processing dependencies for pywinauto==0.6.0rc1

error when comtypes 1.1.3 is not installed: (downloading does not work for my development machine because it is behind firewall and it is blocked)

Installed c:\python27\lib\site-packages\pywinauto-0.6.0rc1-py2.7.egg
Processing dependencies for pywinauto==0.6.0rc1
Searching for comtypes
Reading https://pypi.python.org/simple/comtypes/
Download error on https://pypi.python.org/simple/comtypes/: timed out -- Some pa
ckages may not be found!
Couldn't find index page for 'comtypes' (maybe misspelled?)
Scanning index of all packages (this may take a while)
Reading https://pypi.python.org/simple/
Download error on https://pypi.python.org/simple/: timed out -- Some packages ma
y not be found!
No local packages or download links found for comtypes
error: Could not find suitable distribution for Requirement.parse('comtypes')

from pywinauto.

vasily-v-ryabov avatar vasily-v-ryabov commented on May 19, 2024

Using pip in restricted environments where PyPI is not available is always painful. Though pip has command line option --proxy (helpful if you have internal proxy as a gateway to the big world).

from pywinauto.

nimuston avatar nimuston commented on May 19, 2024

i got it to work :) if i use click_input() method it works and no errors :)

button = window.child_window(auto_id='_buttonName_1')
dlg = button.wrapper_object()
dlg.click_input()

from pywinauto.

vasily-v-ryabov avatar vasily-v-ryabov commented on May 19, 2024

Cool, though click_input makes most natural click and requires active desktop. See #247 if you will need to run it remotely and maybe nightly.

Regarding more silent click()... For "win32" wrappers we use SendMessageTimeout instead of blocking SendMessage to handle situations like you described. For example, if the click opens some dialog and waits for it to close. Will think about kinda the same for "uia".

from pywinauto.

nimuston avatar nimuston commented on May 19, 2024

jeah thats true click_input() is not working for me. To happy to soon :) click() work fine for my test app, but in real use it is waiting for something. How should I handle this wait? in real use I'm clicking a button that opens new window where is should do something else, but now that it is waiting for something and if I let I wait it will take about 1 minute and then script fails.

from pywinauto.

nimuston avatar nimuston commented on May 19, 2024

aaa now I understand, you mean that is should do it like this?

dlg = button.wrapper_object()
win32api.SendMessage(handle, dlg.invoke(), 0, 0)

This actually might work, only thing is that SendMessage() only accepts integer
parameters as far as I know. I can always put it inside a try statement

from pywinauto.

airelil avatar airelil commented on May 19, 2024

@nimuston, your example with SendMessage is just wrong. In fact, you are not supposed to go down to win32 API. At least with the normal Pywinauto usage. If your call to click method is stuck for a while it just means that Pywinauto can't find the control that you try to click. Most likely it's because your window specification is wrong. If you open another window you should make sure you have specified the "dialog" and its control right. Check it step-by-step with draw_outline method:

  • verify your access to this new window : app.NewWindowTitle.draw_outline()
  • after that check that you have found your control: app.NewWindowTitle.ButtonName.draw_outline()

Notice that there is no guarantee that automation IDs are unique (https://msdn.microsoft.com/en-us/library/aa349646(v=vs.110).aspx) so it can be a case that you attempt to automate a different control that doesn't support "Invoke".
As already suggested, use Inspect.exe to find out controls locations and properties. Don't forget to switch Inspect.exe into UIA mode.

from pywinauto.

nimuston avatar nimuston commented on May 19, 2024

@airelil if I call click() method it is able to find the button and it will press it, it just gets stuck after that and it will give we the error message which I described.

from pywinauto.

nimuston avatar nimuston commented on May 19, 2024

it seems that click() method works just fine if I have for example app where the winform title is same all the time. Example calculator if I automate it to press button's based on automationID it works, but if I have app where I'm example pressing login button and then it opens login screen click() method fails and I get that error message. It is able to press the login button and everything is ok on that side, but because I'm getting this error message the script is not able to continue with the rest of the code.

Any idea how I should do this?

from pywinauto.

vasily-v-ryabov avatar vasily-v-ryabov commented on May 19, 2024

it seems that click() method works just fine if I have for example app where the winform title is same all the time.

Not sure I got it clear without a traceback. If the title is changed, you also need to create new window specification.

dlg = app["First window title"]
dlg.SomeButton.click()
# do some other stuff, open some file maybe

# here the title is changed (dlg.SomeButton.click() won't work with ElementNotFound exception)
dlg = app["Second Window Title"]
dlg.SomeButton.click() # should work again

If you're talking about the same issue as for ctypes.COMError: (-2147220991, 'An event was unable to invoke any of the subscribers' it might be more interesting. Is it possible to prepare isolated example to reproduce it on our side?

from pywinauto.

nimuston avatar nimuston commented on May 19, 2024

@vasily-v-ryabov hi, were you able to reproduce this error? now I started to investigating this again and noticed that sometimes I get this pywinauto.findwindows.ElementNotFoundError: 'title': 'Login', 'backend': u'uia'}
but I modified the code a little bit and then once again I get this ctypes.COMError: (-2147220991, 'An event was unable to invoke any of the subscribers' error


from pywinauto.application import Application
import time

app = Application(backend='uia')
app.Start(r'D:\LoginApplication.exe')
time.sleep(1)
app.Connect(title='Login')
handle = app.window_(title='Login')
button = handle.child_window(auto_id='btn_Submit')
dlg = button.wrapper_object()
dlg.draw_outline()
dlg.click()

from pywinauto.

nimuston avatar nimuston commented on May 19, 2024

I have one solution for this problem, more like workaround.

I added one new method to class WindowSpecification. Method name print_control_identifiers_return_control_text()


def print_control_identifiers_return_control_text(self, depth = 2):

        # Wrap this control
        this_ctrl = self.__resolve_control(self.criteria)[-1]

        return (u"{text}".format(
                    text=this_ctrl.window_text()))

It simply returns buttons text value. So my script look like this


from pywinauto.application import Application
import win32gui

app = Application(backend='uia')
app.Connect(title='Login')
handle = app.window_(title='Login')
button = handle.child_window(auto_id='btn_Submit')
button_text = button.print_control_identifiers_return_control_text()

newhandle = win32gui.FindWindow(None, 'Login')
win32gui.SetForegroundWindow(newhandle)
app2 = Application()
app2.Connect(title='Login')
window = app2.window_(title='Login')
pressbutton = window[str(button_text)]
pressbutton.Click()

and to understand why this workaround, the original problem was that I wanted to find and press buttons based on automationID. Now that it is possible with backend='uia' to find buttons based with automationID but it is not possible to use click() method(in some cases). Now i'm returning buttons text from the button that was found with automationID and pressing the button then with the "old" way.

I hope that this is just a temporary solution and click() method problem will be fixed?

from pywinauto.

vasily-v-ryabov avatar vasily-v-ryabov commented on May 19, 2024

Hi @nimuston, so for delayed reply. Was a bit busy and mostly offline this weekend. Thanks a lot for the provided example. Will investigate it soon.

Probably in this case ElementNotFoundError should be raised every time. COMError should be handled on a lower level (as it was fixed in PR #251). The reason for ElementNotFoundError is a target for investigation.

from pywinauto.

nimuston avatar nimuston commented on May 19, 2024

click_input() method works yes, but for test automation it would be better to use click() method. As @vasily-v-ryabov told earlier "click_input makes most natural click and requires active desktop."

from pywinauto.

airelil avatar airelil commented on May 19, 2024

@nimuston, please notice that MS explicitly specifies that Invoke has to be asynchronous exactly for the modal dialog problem. However the demo app isn't complaint to this requirement and apparently the application you try to automate is too. So, if click_input() isn't the option for you, you may use type_keys method to press 'Enter' key:

login_dlg.child_window(auto_id="btn_Submit").set_focus().type_keys("{ENTER}")

Also, if you run on Py3 you may want to play with asyncio or perform a call to click() from another thread as suggested in my previous link

from pywinauto.

nimuston avatar nimuston commented on May 19, 2024

@airelil method type_keys works for me if the button belongs to class "WindowsForms10.BUTTON..." but i also need something for STATIC buttons that belongs to class "WindowsForms10.STATIC....". I thought that the behavior between these is the same but it seems that's it not.

from pywinauto.

airelil avatar airelil commented on May 19, 2024

Could you provide an example that reproduces the problem?

from pywinauto.

vasily-v-ryabov avatar vasily-v-ryabov commented on May 19, 2024

Static control cannot have keyboard focus. So type_keys('{ENTER}') won't work even if you try to press Enter manually.

from pywinauto.

nimuston avatar nimuston commented on May 19, 2024

for this i don't have any demo apps. At least now it seems that only way to click static buttons is to use click()or click_input() method, but because click() gives this comtypes error and click_input() needs active window i'm not able to use either of those.

from pywinauto.

nimuston avatar nimuston commented on May 19, 2024

i actually noticed that the error message is different if i use invoke() method to static button.

Traceback (most recent call last):
  File "<pyshell#13>", line 1, in <module>
    dlg.invoke()
  File "build\bdist.win-amd64\egg\pywinauto\controls\uiawrapper.py", line 409, in invoke
    self.iface_invoke.Invoke()
  File "build\bdist.win-amd64\egg\pywinauto\controls\uiawrapper.py", line 129, in __get__
    value = self.fget(obj)
  File "build\bdist.win-amd64\egg\pywinauto\controls\uiawrapper.py", line 227, in iface_invoke
    return uia_defs.get_elem_interface(elem, "Invoke")
  File "build\bdist.win-amd64\egg\pywinauto\uia_defines.py", line 219, in get_elem_interface
    raise NoPatternInterfaceError()
NoPatternInterfaceError

from pywinauto.

nimuston avatar nimuston commented on May 19, 2024

i'm trying to access static type button with that example, but i will come back to this when i have demo app that i can give you guys. Anyways thank you for the help

from pywinauto.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.