Pywinauto: How to get/read msg text?

Created on 11 May 2018  Â·  13Comments  Â·  Source: pywinauto/pywinauto

Hi,
I am trying to get/read msg text in pywinauto script and getting problem.

print_control_identifiers() gives me the following control:

Image - ''    (L566, T382, R614, B478)
   |    |    | ['3', 'Image', 'Image0', 'Image1']
   |    |    | child_window(auto_id="MessageIcon", control_type="Image")
   |    |    |
   |    |    | Static - ''    (L659, T374, R1049, B401)
   |    |    | ['4', 'Static4']
   |    |    | child_window(auto_id="HeaderConfigurable", control_type="Text")
   |    |    |    |
   |    |    |    | Static - 'Validation'    (L659, T374, R1049, B401)
   |    |    |    | ['Static5', 'Validation', 'ValidationStatic', 'Validation0', 'Validation1', 'ValidationStatic0', 'ValidationStatic1']
   |    |    |    | child_window(title="Validation", auto_id="PART_Label", control_type="Text")
   |    |    |    |    |
   |    |    |    |    | Static - 'Validation'    (L659, T374, R754, B401)
   |    |    |    |    | ['Static6', 'Validation2', 'ValidationStatic2']
   |    |    |    |    | child_window(title="Validation", control_type="Text")

I tried the following:

sMsg=cMyApp1.dialog.child_window(class_name="TextBlock",auto_id="PART_TextBlock")
s=sMsg.legacy_properties()['Name']
print(s)

but it's not working.


Inspect .exe shows the following...

How found:  Selected from tree...
Name:   "The ID Code value is duplicate."
ControlType:    UIA_TextControlTypeId (0xC364)
LocalizedControlType:   "text"
BoundingRectangle:  {l:669 t:447 r:1029 b:463}
IsEnabled:  true
IsOffscreen:    false
IsKeyboardFocusable:    false
HasKeyboardFocus:   false
AcceleratorKey: ""
AccessKey:  ""
ProcessId:  3704
RuntimeId:  [7.E78.2011D81]
AutomationId:   "PART_TextBlock"
FrameworkId:    "WPF"
ClassName:  "TextBlock"
IsControlElement:   false
IsContentElement:   false
ProviderDescription:    "[pid:3704,providerId:0x0 Main(parent link):Unidentified Provider (managed:MS.Internal.Automation.ElementProxy, PresentationCore, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35)]"
IsPassword: false
ItemStatus: ""
ItemType:   ""
IsRequiredForForm:  false
HelpText:   ""
ClickablePoint: {x:849 y:455}
Orientation:    0
LegacyIAccessible.ChildId:  0
LegacyIAccessible.DefaultAction:    ""
LegacyIAccessible.Description:  ""
LegacyIAccessible.Help: ""
LegacyIAccessible.KeyboardShortcut: ""
LegacyIAccessible.Name: "The ID Code value is duplicate."
LegacyIAccessible.Role: text (0x29)
LegacyIAccessible.State:    normal (0x0)
LegacyIAccessible.Value:    ""
Selection2.FirstSelectedItem:   [Not supported]
Selection2.LastSelectedItem:    [Not supported]
Selection2.CurrentSelectedItem: [Not supported]
Selection2.ItemCount:   [Not supported]
IsAnnotationPatternAvailable:   false
IsDragPatternAvailable: false
IsDockPatternAvailable: false
IsDropTargetPatternAvailable:   false
IsExpandCollapsePatternAvailable:   false
IsGridItemPatternAvailable: false
IsGridPatternAvailable: false
IsInvokePatternAvailable:   false
IsItemContainerPatternAvailable:    false
IsLegacyIAccessiblePatternAvailable:    true
IsMultipleViewPatternAvailable: false
IsObjectModelPatternAvailable:  false
IsRangeValuePatternAvailable:   false
IsScrollItemPatternAvailable:   false
IsScrollPatternAvailable:   false
IsSelectionItemPatternAvailable:    false
IsSelectionPatternAvailable:    false
IsSpreadsheetItemPatternAvailable:  false
IsSpreadsheetPatternAvailable:  false
IsStylesPatternAvailable:   false
IsSynchronizedInputPatternAvailable:    true
IsTableItemPatternAvailable:    false
IsTablePatternAvailable:    false
IsTextChildPatternAvailable:    false
IsTextEditPatternAvailable: false
IsTextPatternAvailable: false
IsTextPattern2Available:    false
IsTogglePatternAvailable:   false
IsTransformPatternAvailable:    false
IsTransform2PatternAvailable:   false
IsValuePatternAvailable:    false
IsVirtualizedItemPatternAvailable:  false
IsWindowPatternAvailable:   false
IsCustomNavigationPatternAvailable: false
IsSelectionPattern2Available:   [Not supported]
FirstChild: [null]
LastChild:  [null]
Next:   [null]
Previous:   "" text
Other Props:    Object has no additional properties
Children:   Container has no children

Thanks in advance.
Smita

question

All 13 comments

Hi @smitagodbole the code looks adequate.

sMsg=cMyApp1.dialog.child_window(class_name="TextBlock",auto_id="PART_TextBlock")
s=sMsg.legacy_properties()['Name']
print(s)

What's exactly not working here? Please provide full exception traceback (crash stack). Without it I can make assumptions only.

Maybe dialog name could be closer to cMyApp1.SunriseClinicalManager instead of cMyApp1.dialog.

One more important thing: is this window top level? You must start window lookup from the top level only. Like this:

dialog = cMyApp1.SunriseClinicalManagerConfigurationTools.child_window(title="Sunrise Clinical Manager", control_type="Window")
sMsg = dialog.child_window(class_name="TextBlock",auto_id="PART_TextBlock")
s = sMsg.legacy_properties()['Name']
print(s)

Obviously you've started not from top level window. The top level one is "Sunrise Clinical Manager Configuration Tools" (immediate child of desktop/root element). So the correct code is:

top_level_main_window = cMyApp1.window(title="Sunrise Clinical Manager Configuration Tools", control_type="Window")
top_level_main_window.wrapper_object() # should pass if found
nPDialog = top_level_main_window.child_window(title="New Procedure", control_type="Window")
nPDialog.wrapper_object() # should pass if subdialog is found
dialog = sUrgicalCareDialog.nPDialog.child_window(title="Sunrise Clinical Manager", control_type="Window")
dialog.wrapper_object() # should pass if subdialog is found
#sMsg = dialog.child_window(title="Sunrise Clinical Manager", control_type="Window")
sMsg=dialog.child_window(class_name="TextBlock",auto_id="PART_TextBlock")
s=sMsg.legacy_properties()['Name']
print(s)

Now if it fails, it's more clear which step is incorrect. .wrapper_object() calls actual window search.

The core concept about window specifications and wrappers is described in the Getting Started Guide.

Of course, .wrapper_object() calls are for debug purpose only. When you call .legacy_properties() it performs actual search inside for the whole chain. Previously (without .wrapper_object()) only window specifications were created.

Hi,
Sorry couldn't get bact immediately as got busy with other stuff. I tried the way you suggested and its not working. Here is the stack trace of that...

Traceback (most recent call last):
  File "Surgery-Dictionary.py", line 65, in <module>
    top_level_main_window.wrapper_object() # should pass if found
  File "C:\python36\lib\site-packages\pywinauto-0.6.4-py3.6.egg\pywinauto\application.py", line 254, in wrapper_object
  File "C:\python36\lib\site-packages\pywinauto-0.6.4-py3.6.egg\pywinauto\application.py", line 248, in __resolve_control
  File "C:\python36\lib\site-packages\pywinauto-0.6.4-py3.6.egg\pywinauto\timings.py", line 427, in wait_until_passes
  File "C:\python36\lib\site-packages\pywinauto-0.6.4-py3.6.egg\pywinauto\application.py", line 209, in __get_ctrl
  File "C:\python36\lib\site-packages\pywinauto-0.6.4-py3.6.egg\pywinauto\findwindows.py", line 87, in find_element
pywinauto.findwindows.ElementNotFoundError: {'title': 'Sunrise Clinical Manager Configuration Tools', 'control_type': 'Window', 'top_level_only': False, 'parent': <uia_element_info.UIAElementInfo - 'Sunrise Clinical Manager Configuration Tools', ClsConfigurationTools, 2822444>, 'backend': 'uia'}

Thanks
Smita

OK, to determine the exact title of top level window try this code:

print([win.window_text() for win in cMyApp1.windows()])

And how do you create cMyApp1 object? Looks like it's not an Application one, but another window specification. How did I understand that? The exception tells that window with title='Sunrise Clinical Manager Configuration Tools' should have parent with the same title. So this is a duplication. Please clarify things in more details to avoid such a confusion.

Also if you create window spec from Application object, the first level search criteria would contain 'top_level_only': True, but you have 'top_level_only': False.

OK, with full code sample it's easier to figure out every problem.

This is correct code to determine exact title of top level window (capp is the Application object I told about):

for win in capp.windows():
    print(win.window_text())

Now you're almost done except the text block search (all previous parents seem found well).
To make sure this text block is accessible in the hierarchy try this dump:

dialog.print_control_identifiers()

Maybe something like that would work:

sMsg = dialog.child_window(auto_id="PART_TextBlock", control_type="Text")
sMsg.window_text() # normal "Name" property looks the same as legacy one

The top window is obviously visible despite it's behind current active dialog. It's just inactive from focus point of view. For truly invisible windows/elements you have to add visible_only=False to the child_window criteria. Otherwise they shouldn't be found.

Hi Vasily,Tried and got following...Control Identifiers:
Dialog -  |   | TitleBar - ''    (L557, T328, R1059, B356)   | ['', 'TitleBar', '0', '1']   |    |   |    | Menu - 'System'    (L541, T333, R563, B355)   |    | ['SystemMenu', 'Menu', 'System', 'System0', 'System1']   |    | child_window(title="System", auto_id="MenuBar", control_type="MenuBar")   |    |    |   |    |    | MenuItem - 'System'    (L541, T333, R563, B355)   |    |    | ['MenuItem', 'System2', 'SystemMenuItem']   |    |    | child_window(title="System", control_type="MenuItem")   |    |   |    | Button - 'Close'    (L1026, T326, R1060, B356)   |    | ['Button', 'Close', 'CloseButton', 'Button0', 'Button1']   |    | child_window(title="Close", control_type="Button")   |   | Hyperlink - ''    (L551, T496, R613, B512)   | ['2', 'Hyperlink']   | child_window(auto_id="HelpLink", control_type="Hyperlink")   |    |   |    | Button - 'Need Help?'    (L551, T496, R613, B512)   |    | ['Button2', 'Need Help?Button', 'Need Help?', 'Need Help?0', 'Need Help?1']   |    | child_window(title="Need Help?", auto_id="PART_LinkLabel", control_type="Button")   |    |    |   |    |    | Static - 'Need Help?'    (L551, T496, R613, B512)   |    |    | ['Static', 'Need Help?Static', 'Need Help?2', 'Static0', 'Static1']   |    |    | child_window(title="Need Help?", control_type="Text")   |   | Button - 'OK'    (L984, T490, R1049, B518)   | ['Button3', 'OK', 'OKButton', 'OK0', 'OK1', 'OKButton0', 'OKButton1']   | child_window(title="OK", auto_id="_btnOK", control_type="Button")   |    |   |    | Button - 'OK'    (L984, T490, R1049, B518)   |    | ['Button4', 'OK2', 'OKButton2']   |    | child_window(title="OK", auto_id="PART_Button", control_type="Button")   |    |    |   |    |    | Static - 'OK'    (L1003, T491, R1030, B517)   |    |    | ['Static2', 'OK3', 'OKStatic', 'OKStatic0', 'OKStatic1']   |    |    | child_window(title="OK", auto_id="contentPresenter", control_type="Text")   |    |    |    |   |    |    |    | Static - 'OK'    (L1008, T496, R1025, B512)   |    |    |    | ['Static3', 'OK4', 'OKStatic2']   |    |    |    | child_window(title="OK", control_type="Text")   |   | Image - ''    (L566, T382, R614, B478)   | ['3', 'Image']   | child_window(auto_id="MessageIcon", control_type="Image")   |   | Static - ''    (L659, T374, R1049, B401)   | ['4', 'Static4']   | child_window(auto_id="HeaderConfigurable", control_type="Text")   |    |   |    | Static - 'Validation'    (L659, T374, R1049, B401)   |    | ['Validation', 'Static5', 'ValidationStatic', 'Validation0', 'Validation1', 'ValidationStatic0', 'ValidationStatic1']   |    | child_window(title="Validation", auto_id="PART_Label", control_type="Text")   |    |    |   |    |    | Static - 'Validation'    (L659, T374, R754, B401)   |    |    | ['Validation2', 'Static6', 'ValidationStatic2']   |    |    | child_window(title="Validation", control_type="Text")Traceback (most recent call last):  File "C:\python36\lib\site-packages\pywinauto-0.6.4-py3.6.egg\pywinauto\application.py", line 245, in __resolve_control  File "C:\python36\lib\site-packages\pywinauto-0.6.4-py3.6.egg\pywinauto\timings.py", line 449, in wait_until_passespywinauto.timings.TimeoutError
During handling of the above exception, another exception occurred:
Traceback (most recent call last):  File "Surgery-Dictionary.py", line 63, in     sMsg.window_text()  File "C:\python36\lib\site-packages\pywinauto-0.6.4-py3.6.egg\pywinauto\application.py", line 351, in __getattribute__  File "C:\python36\lib\site-packages\pywinauto-0.6.4-py3.6.egg\pywinauto\application.py", line 248, in __resolve_control  File "C:\python36\lib\site-packages\pywinauto-0.6.4-py3.6.egg\pywinauto\timings.py", line 427, in wait_until_passes  File "C:\python36\lib\site-packages\pywinauto-0.6.4-py3.6.egg\pywinauto\application.py", line 209, in __get_ctrl  File "C:\python36\lib\site-packages\pywinauto-0.6.4-py3.6.egg\pywinauto\findwindows.py", line 87, in find_elementpywinauto.findwindows.ElementNotFoundError: {'class_name': 'TextBlock', 'auto_id': 'PART_TextBlock', 'top_level_only': False, 'parent': C:\Download\Pywinauto 0.6.4\Scripts>
It looks like msg "The ID code value is duplicate" is not getting captured when I use print_control_identifiers().
ThanksSmita

On Wednesday, May 23, 2018 4:52 PM, Vasily Ryabov <[email protected]> wrote:

OK, with full code sample it's easier to figure out every problem.This is correct code to determine exact title of top level window (capp is the Application object I told about):for win in capp.windows():
print(win.window_text())Now you're almost done except the text block search (all previous parents seem found well).
To make sure this text block is accessible in the hierarchy try this dump:dialog.print_control_identifiers()Maybe something like that would work:sMsg = dialog.child_window(auto_id="PART_TextBlock", control_type="Text")
sMsg.window_text() # normal "Name" property looks the same as legacy oneThe top window is obviously visible despite it's behind current active dialog. It's just inactive from focus point of view. For truly invisible windows/elements you have to add visible_only=False to the child_window criteria. Otherwise they shouldn't be found.—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.

Well, this is interesting case. It seems we need a Skype call with sharing desktop. My Skype ID can be found by "vasily-v-ryabov".replace("-", ".").

Hi,
Vasily, I am so sorry but I am not allowed to do skype due to security. So I will prefer to stop working on this test case and will move on next.
Thanks a lot for your help.
Smita

OK, it's up to you. No problem to sign NDA for me and use another software for meeting. If it's important enough, you're always welcome back.

Hi Vasily,
I am sorry I was not clear enough.  I am going to use this tool and want to learn it more.  Actually I already started working on another test case. Even though I have given a demo to our group and managers and everyone liked the tool as well.  Only I was told that they haven't finalized on this tool and once they finalized then I might share some of the information.  By the way I don't understand "Sign NDA" part which you mentioned in the email. 
Once I get permission I will open this test case again.  Until then I am using workaround for duplicate ID issue by using random function to add new Id.
ThanksSmita

On Thursday, May 31, 2018 7:21 AM, Vasily Ryabov <[email protected]> wrote:

OK, it's up to you. No problem to sign NDA for me and use another software for meeting. If it's important enough, you're always welcome back.—
You are receiving this because you modified the open/close state.
Reply to this email directly, view it on GitHub, or mute the thread.

Yes, I understood that you're still using pywinauto. Good to hear positive feedback. I told just about this case. Don't worry.

NDA is a "non-disclosure agreement". It's common practice for consulting on private cases. So I consider Skype meeting as a private discussion. Of course, you probably need an approval even for private sharing. This is just for your information.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mtkennerly picture mtkennerly  Â·  14Comments

MyerFire picture MyerFire  Â·  37Comments

jjbright picture jjbright  Â·  15Comments

yangliang003 picture yangliang003  Â·  18Comments

vasily-v-ryabov picture vasily-v-ryabov  Â·  36Comments