WPF Pane - Read Text using PyWinAuto - wpf

I am trying to read text from WPF pane window. Previously this windows was a normal win32 windows. So my automated script was working fine. Now since the developer has changed it to WPF; Swapy.exe is unable to detect it. So I tried the UIA approach and use Inspect.exe.
The challenge which I am facing is how to use Inspect.exe and pywinauto together to read the text data.
Is there any way we can read text from WPF pane window?
Here I am coping the pane window details which I got from Inspect.exe
How found: Focus
Name: ""
ControlType: UIA_PaneControlTypeId (0xC371)
LocalizedControlType: "pane"
BoundingRectangle: {l:639 t:541 r:1337 b:657}
IsEnabled: true
IsOffscreen: false
IsKeyboardFocusable: true
HasKeyboardFocus: true
AcceleratorKey: ""
AccessKey: ""
ProcessId: 17928
RuntimeId: [7.4608.364D350]
AutomationId: ""
FrameworkId: "WPF"
ClassName: "ScrollViewer"
IsControlElement: true
IsContentElement: true
ProviderDescription: "[pid:17928,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:988 y:599}
Orientation: 0
LegacyIAccessible.ChildId: 0
LegacyIAccessible.DefaultAction: ""
LegacyIAccessible.Description: ""
LegacyIAccessible.Help: ""
LegacyIAccessible.KeyboardShortcut: ""
LegacyIAccessible.Name: ""
LegacyIAccessible.Role: pane (0x10)
LegacyIAccessible.State: focused,focusable (0x100004)
LegacyIAccessible.Value: ""
Scroll.HorizontallyScrollable: false
Scroll.HorizontalScrollPercent: -1.000000
Scroll.HorizontalViewSize: 100.000000
Scroll.VerticallyScrollable: false
Scroll.VerticalScrollPercent: -1.000000
Scroll.VerticalViewSize: 100.000000
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: true
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: false
FirstChild: "" text
LastChild: "" scroll bar
Next: [null]
Previous: [null]
Other Props: Object has no additional properties
Children: "" text
"0x5107:031 Cycle length" text
"Value:" text
"14405 Unit" text
"Factory setting:" text
"360 Unit" text
"Range:" text
"0.000000001 ... 2147483647 Unit" text
"Raw value:" text
"14405 (0x000000008022CC40)" text
"Data type:" text
"LREAL - IEEE 754 Long Real (8 bytes)" text
"Note:" text
"PC must be inhibited before write operation!" text
"" text
"" scroll bar
"" scroll bar
Ancestors: "" custom
"" custom
"elementHost" pane
"elementHost" pane
"" pane
"Filter active!" pane
"" pane
"" pane
"" pane
"" pane
"" pane
"" pane
"Parameter list" pane
"" tab
"" pane
"" pane
"Device" pane
"" pane
"UpdateMotionAxesABC_OldVersion.prj - My Applicaiton 3.21.0" window
"Desktop 1" pane
[ No Parent ]

I was able to read the text. see below code snippet
from pywinauto.application import Application
from pywinauto import application
plcPid = application.process_from_module(module = 'MyApp.exe')
wpfApp = Application(backend='uia').connect(process=plcPid)
handle = wpfApp.window_(title='MyDoc.project - MyApp 3.21.0')
child = handle.child_window(auto_id='elementHostInfoBox')
child0 = child.wrapper_object()
child1 = child0.children()
child2 = child1[0].children()
child3 = child2[0].children()
print(child3[0].children_texts())

Hi Sachin,
Even i am facing a similar issue and not able to read the text present in the text box,
coping the pane window details which I got from Inspect.exe
How found: Mouse move (481,182)
hwnd=0x00060E74 32bit class="HwndWrapper[IKEA.Mfs.Sales.App.iSell.exe;;983a900c-7814-40e2-a87e-ab06b28a7dd5]" style=0x56010000 RuntimeId: "[7.12692.48621330]"
BoundingRectangle: {l:470 t:174 r:666 b:194}
ProcessId: 12692
ControlType: UIA_EditControlTypeId (0xC354)
LocalizedControlType: "edit"
Name: ""
AcceleratorKey: ""
AccessKey: ""
HasKeyboardFocus: true
IsKeyboardFocusable: true
IsEnabled: true
AutomationId: "TextboxContactMethodEmailData"
ClassName: "TextBox"
HelpText: ""
ClickablePoint: {x:568 y:184}
IsControlElement: true
IsContentElement: true
IsPassword: false
ItemType: ""
IsOffscreen: false
Orientation: 0
FrameworkId: "WPF"
IsRequiredForForm: false
ItemStatus: ""
ProviderDescription: "[pid:12692,providerId:0x0 Main(parent link):Unidentified Provider (managed:MS.Internal.Automation.ElementProxy, PresentationCore, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35)]"
Value.IsReadOnly: false
Value.Value: "test#test.com"
Scroll.HorizontalScrollPercent: -1.000000
Scroll.HorizontalViewSize: 100.000000
Scroll.VerticalScrollPercent: -1.000000
Scroll.VerticalViewSize: 100.000000
Scroll.HorizontallyScrollable: false
Scroll.VerticallyScrollable: false
IsDockPatternAvailable: false
IsExpandCollapsePatternAvailable: false
IsGridItemPatternAvailable: false
IsGridPatternAvailable: false
IsInvokePatternAvailable: false
IsMultipleViewPatternAvailable: false
IsRangeValuePatternAvailable: false
IsScrollPatternAvailable: true
IsScrollItemPatternAvailable: false
IsSelectionItemPatternAvailable: false
IsSelectionPatternAvailable: false
IsTablePatternAvailable: false
IsTableItemPatternAvailable: false
IsTextPatternAvailable: true
IsTogglePatternAvailable: false
IsTransformPatternAvailable: false
IsValuePatternAvailable: true
IsWindowPatternAvailable: false
IsItemContainerPatternAvailable: false
IsVirtualizedItemPatternAvailable: false
FirstChild: "" pane
LastChild: "" pane
Next: "" radio button
Previous: "Email" text
Other Props: Object has no additional properties
Children: "" pane
Ancestors: "" custom
"" custom
"Preferred way of communication" group
"" custom
"Billing info" group
"" pane
"" custom
"" custom
"IcmCustomerHost" pane
"IcmCustomerHost" pane
"Customer Profile - Private" window
"iSell (CTE-F2)2" window
"Desktop 1" pane
[ No Parent ]
Please do help me how can i read text inside a text box or set some value in text box,

My application is not completely of wpf panes . it has a win32 forms in the home page and when i click a button to create a customer it will be navigated to a window which id of wpf and there i am able to wrap only the title of the window and don't see any descendents like textboxes and buttons using swappy like below
def wpftesting():
app=Application().connect(title=u'Customer Profile - Private', class_name='WindowsForms10.Window.8.app.0.21093c0_r30_ad1')
fC_window = app[u'Customer Profile - Private']
fC_window.print_control_identifiers()
this is what i see only the title of the pane
Control Identifiers:
WindowsForms10.Window.8.app.0.21093c0_r30_ad1 - 'Customer Profile - Private' (L341, T42, R1025, B686)
['WindowsForms10.Window.8.app.0.21093c0_r30_ad1', 'Customer Profile - PrivateWindowsForms10.Window.8.app.0.21093c0_r30_ad1', 'Customer Profile - Private', 'WindowsForms10.Window.8.app.0.21093c0_r30_ad10', 'WindowsForms10.Window.8.app.0.21093c0_r30_ad11']
child_window(title="Customer Profile - Private", auto_id="IcmCustomerUi", control_type="IKEA.Mfs.Icm.Uil.Icm.Ui.IcmCustomerUi")
|
| WindowsForms10.Window.8.app.0.21093c0_r30_ad1 - 'IcmCustomerHost' (L349, T73, R1017, B656)
| ['IcmCustomerHost', 'WindowsForms10.Window.8.app.0.21093c0_r30_ad12', 'IcmCustomerHostWindowsForms10.Window.8.app.0.21093c0_r30_ad1', 'IcmCustomerHost0', 'IcmCustomerHost1']
| child_window(title="IcmCustomerHost", auto_id="IcmCustomerHost", control_type="System.Windows.Forms.Integration.ElementHost")
| |
| | HwndWrapper[IKEA.Mfs.Sales.App.iSell.exe;;c2aeda95-6754-42bc-9936-9f13c37a34df] - 'IcmCustomerHost' (L349, T73, R1017, B656)
| | ['IcmCustomerHostHwndWrapper[IKEA.Mfs.Sales.App.iSell.exe;;c2aeda95-6754-42bc-9936-9f13c37a34df]', 'HwndWrapper[IKEA.Mfs.Sales.App.iSell.exe;;c2aeda95-6754-42bc-9936-9f13c37a34df]', 'IcmCustomerHost2']
| | child_window(title="IcmCustomerHost", class_name="HwndWrapper[IKEA.Mfs.Sales.App.iSell.exe;;c2aeda95-6754-42bc-9936-9f13c37a34df]")
|
| HwndWrapper[IKEA.Mfs.Sales.App.iSell.exe;;c2aeda95-6754-42bc-9936-9f13c37a34df] - 'IcmCustomerHost' (L349, T73, R1017, B656)
| ['IcmCustomerHostHwndWrapper[IKEA.Mfs.Sales.App.iSell.exe;;c2aeda95-6754-42bc-9936-9f13c37a34df]', 'HwndWrapper[IKEA.Mfs.Sales.App.iSell.exe;;c2aeda95-6754-42bc-9936-9f13c37a34df]', 'IcmCustomerHost2']
| child_window(title="IcmCustomerHost", class_name="HwndWrapper[IKEA.Mfs.Sales.App.iSell.exe;;c2aeda95-6754-42bc-9936-9f13c37a34df]")
|
| StatusBar - '' (L349, T656, R1017, B678)
| ['Customer Profile - PrivateStatusBar', 'StatusBar']
| child_window(auto_id="StatusBar1", control_type="IKEA.Mdif.Sys.Uil.MdifStatusBar")
. As mentioned to use backend='uia' for wpf panes and it throws an error like below
def wpftesting():
app=Application(backend='uia').connect(title=u'Customer Profile - Private', class_name='WindowsForms10.Window.8.app.0.21093c0_r30_ad1')
fC_window = app[u'Customer Profile - Private']
fC_window.print_control_identifiers()
pywinauto.findwindows.ElementNotFoundError: {'title': 'Customer Profile - Private', 'class_name': 'WindowsForms10.Window.8.app.0.21093c0_r30_ad1', 'backend': 'uia', 'visible_only': False}
. No idea how to use this inspect.exe tool found properties in pywinauto. can you please post some sample code like def delivery_questionaries():
dQ = Application().connect(title=u'Delivery questions', class_name='WindowsForms10.Window.8.app.0.21093c0_r30_ad1')
dQ_window = dQ[u'Delivery questions']
dQ_window.set_focus()
Thanks in advance

I am also new to UIA but have worked mostly on Win32, I came up with code based upon input provided by you -
from pywinauto.application import Application
from pywinauto import application
plcPid = application.process_from_module(module = 'yourexe.exe')
wpfApp = Application(backend='uia').connect(process=plcPid)
wind = wpfApp.windows()
title = wind[0].get_properties()[u'texts'][0]
print(title) # should print title of your application window
handle = wpfApp.window(title = title)
child = handle.child_window(auto_id='TextboxContactMethodEmailData')
child1 = child.wrapper_object()
print(child1[0].children_texts())

Related

Is it possible to extract audio from soundcloud-widget

I have a p5 canvas that makes visuals accords to the song it plays.
I try to add SoundCloud-widget as another music resource for user (and not just local uploading).
Are there is a way to extract the audio/blob/m3u8 from the widget? just set the display of the widget to "none" it is not enough because the song not going through p5 canvas.
The widget sends the music in HLS protocol, however when getting into network tab and filter for m3u8 couldn't find anything.
Right now I've got from
widget.getCurrentSound(currentSound => {
console.log(currentSound)
}
in my console -
artwork_url: 'https://i1.sndcdn.com/artworks-000217481049-b5k347-large.jpg'
comment_count: 1412
commentable: true
created_at: "2017-04-12T16:00:36Z"
description: ""
display_date: "2017-04-12T16:00:36Z"
domain_lockings: []
download_count: 0
download_url: null
downloadable: false
duration: 262710
embeddable_by: "all"
full_duration: 262710
genre: "Deep House"
has_downloads_left: true
id: 317363228
kind: "track"
label_name: null
last_modified: "2019-08-02T11:58:38Z"
license: "cc-by"
likes_count: 29882
media: {transcodings: Array(2)}
monetization_model: "NOT_APPLICABLE"
permalink: "mysong"
permalink_url: "https://soundcloud.com/...."
playable: true
playback_count: 1549676
policy: "ALLOW"
public: true
publisher_metadata: {urn: "soundcloud:tracks:XXXXXX", artist: "... ", id: 111111111}
purchase_title: "Free Download !"
purchase_url: null
release_date: null
reposts_count: 3378
secret_token: null
sharing: "public"
state: "finished"
streamable: true
tag_list: "my song""
title: "my song"
uri: "https://api.soundcloud.com/tracks/11111"
urn: "soundcloud:tracks:3111111"
user: {soundcloud user obj}
user_id: 11111111
visuals: null
waveform_url: "https://wave.sndcdn.com/XXXXXXX.json"
_resource_id: 11111111
_resource_type: "sound"
__proto__: Object
Thanks in advance :)

How to set a record Dirty ExtJs 6

I want to set a whole record from a store to dirty. I have already tried record.setDirty() but this method is deprecated.
ExtJS Record#Set
The second argument to set accepts an "options" object, where you can specify dirty: true | false
record.set({ name: 'value', age: 42}, {
dirty: true
});
record.set({}, {
dirty: true
});

reactjs pre-select radio button

I have a section in Client`s panel to agree (or not) to receive promo emails.
I set this as a choice of two radio buttons, yes or no.
Technically everything is working just fine, I can store proper information in the DB but the initial state of radio buttons is not showing. The proper value is being sent ot its 'parent' but it seems it's not passed down to the actual form.
What I would like to achieve is the initial radio button being checked (true, false):
The info is being sent (in line 52, [PROMO_CONSENT]: promo_consent):
[PROMO_CONSENT_FORM]: {
label: _t(panelMessages.promos),
data: Promo,
form: {
formId: PROMO_CONSENT_FORM,
data: {
[PROMO_CONSENT]: promo_consent
}
}
}
but then it doesn't seems to show anywhere else. To manage the states of radiobuttons, component FormChoiceGroup is being called component: FormChoiceGroup,.
[PROMO_CONSENT_FORM]: {
formId: [PROMO_CONSENT_FORM],
endpoint: '/accounts/set_promo/',
fields: [
{
name: PROMO_CONSENT,
label: _t(panelMessages.promoLabel),
component: FormChoiceGroup,
type: 'radio',
isRequired: false
}
]
}
It's a lot of code, if anyone feels like going through it, I'd appreciate it.
Block:
Panel main block
Form:
Panel form, the part of consent starts at line 96
ChoiceGroup:
Component to manage radio buttons
I had to send NOT a boolean value, but turn it into a string, to send literal "true" or "false" and not true/false.
I set up a const that checked the status of the variable and then assigned it with literal values:
const val = this.state.formData[field.name] == false ? "false" : "true";
This simple thing did the trick.

How to set status of checkbox to checked on AngularJS belong to the value in array

I have the array of product options that 1 option has been set as a default option. I set it by set the value as 1 for the picked option and 0 for another elements.
<div class="attribute-set" *ngFor="let attr of optionAttrArray; index as i;"><input type="checkbox" name="default" id="option-{{optionAttrArray[i].attribute_id}}" [value]="optionAttrArray[i].set_default" (change)="changeDetault(i)"/></div>
TS file below:
addNewAttribute(){
this.optionAttrArray.push({
attribute_id: "0",
name: '',
price: '',
sku: '',
status: "1",
set_default:"0",
});
}
set_default = 0 mean not picked, 1 mean set as default option
I need to make the checkbox status checked if set_default = 1 when click to edit this attribute group
I've founded the solution by myself. It just the property of the checkbox like this
[checked]="optionAttrArray[i].set_default == 1"

Counting filtered expression

In AngularJS, I would like to show a counter that shows "done/all" tasks for each of the below groups, i.e. in this case :
food: 1/2
hygienics: 0/1
List of tasks:
$tasks = [
{
title: "buy bacon",
group: "food",
done: "true",
},
{
title: "buy tuna",
group: "food",
done: "false",
},
{
title: "buy toothpaste",
group: "hygienics",
done: "false",
},
];
The counter should automatically update whenever I set a task's "done" to "true". So really, I am looking for a nice filtered expression, like the following (but with "done" worked in):
Food: {{ ( tasks | filter: {group:'food'} ).length }}
How can I include "done" into this?
From the documentation:
You can chain filters using this syntax:
{{ expression | filter1 | filter2 }}
so just chain an additional filter:
tasks | filter: {group:'food'} | filter: {done: true}
Or, still from the documentation
expression – {string|Object|function()} –
The predicate to be used for selecting items from array.
Can be one of:
[...]
Object: A pattern object can be used to filter specific properties on objects contained by array. For example {name:"M", phone:"1"} predicate will return an array of items which have property name containing "M" and property phone containing "1".
So you could also use
tasks | filter: {group:'food', done: true}
Not tested, though.

Resources