Sign in to follow this  
Followers 0
souldjer777

Norton Power Eraser - Clicking a button with no text UIA

12 posts in this topic

#1 ·  Posted (edited)

Good Morning AutoIT Gurus :)

I am trying to run Norton Power Eraser automatically and I'm getting stuck by a button that has no text. I'm using junkew's simplespy UIA... Dude, you are the bomb. How you guys can do what you do is beyond me! Thank you!

Okee doke...  here is the Simple UIA Spy info...

Title is: < > Class   := <> controltype:= <UIA_ButtonControlTypeId> ,<50000> , (0000C350) 242;375;177;177
*** Parent Information top down ***
10: Title is: <Desktop> Class   := <#32769> controltype:= <UIA_PaneControlTypeId> ,<50033> , (0000C371) 0;0;1280;1024
"Title:=Desktop;controltype:=UIA_PaneControlTypeId;class:=#32769"
9: Title is: <Norton Power Eraser> Class   := <NortonPowerEraserWnd> controltype:= <UIA_PaneControlTypeId> ,<50033> , (0000C371) 97;192;796;532
 
npw.png
 
It's the yellow button with a white magnifying glass on it (pictured above "Scan for Risks")... Is there a way to identify the button by it's dimensions and click on it???  LOL, Or is there something I'm missing in Simple Spy?
 
NPE.exe is Norton Power Eraser:
 
Thanks Everyone! Sorry to put anyone through this on a Friday.
Edited by souldjer777

"Maybe I'm on a road that ain't been paved yet. And maybe I see a sign that ain't been made yet"
Song Title: I guess you could say
Artist: Middle Class Rut

Share this post


Link to post
Share on other sites



Just force the window to maximize it would put the button same position every time,or just winmove () to 0,0 and it would achieve same effect. This obviously isn't the most elegant solution. I'm sure someone will have better idea. I keep hearing use controlclick () but I can't seem to get it to work.

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

I think I may end up using PixelSearch or something of that nature because there is no information returned from simple spy via the Norton Power Eraser Gui that I can simply identify the button with... as far as I can tell. Nope, nevermind, used window x, y, w, h and then did the math for a mousemove / mouseclick. Very old school but it worked. If junkew saw this, he would know what to do imo.

Edited by souldjer777

"Maybe I'm on a road that ain't been paved yet. And maybe I see a sign that ain't been made yet"
Song Title: I guess you could say
Artist: Middle Class Rut

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Is the button itself highlighted when you press ctrl w on top of it or did you get the whole window highlighted. Check what inspect.exe in windows sdk returns.

Search otherwise for findbmp in the examples forum as an alternative.

Edited by junkew

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

Thanks everyone, the windows inspect.exe shows the same things... basically blank info. I'll do what you suggest junkew - I'll check out the findbmp  :bye: 

How found: Mouse move (446,377)
hwnd=0x00000000000C0230 32bit class="NortonPowerEraserWnd" style=0xFFFFFFFF960A0800 ex=0x40000
Name: " "
ControlType: UIA_ButtonControlTypeId (0xC350)
LocalizedControlType: "button"
 
UPDATE: I checked out the findbmp and it's pretty cool. Works well, the only thing was the instructions were a little off...
 
Sample to work
* Install pics.zip into %temp% / Save BMP attachments for example to @tempdir (%temp%) for example to work
... but in the code it says to check the @scriptdir 
 
Going to try and check out the array output, since even though the picture is found or matched... what can I do with the output? I'll do some more research.
Edited by souldjer777

"Maybe I'm on a road that ain't been paved yet. And maybe I see a sign that ain't been made yet"
Song Title: I guess you could say
Artist: Middle Class Rut

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

Most of the time if I cant click I would go with a WinActivate followed by sending the keystrokes needed to interact without the mouse.  I feel that is more stable/reliable than any mouse cords or image search.

Pretty much what Prodigy posted except instead of sleep use WinWait

So 

Run("NPE.exe")
WinWait("Norton Power Eraser", "")
WinActivate("Norton Power Eraser", "")
Send("{Enter}")
Sleep(1000)
WinWait("Norton Power Eraser", "")
WinActivate("Norton Power Eraser", "")
Send("{Tab 4}")
Send("{Enter}")

Most of the time you can get some text out of a window and not have to use Sleep, but since there is no text I can find there is a sleep between the first window and the 2nd. 

Edited by ViciousXUSMC

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

I have another issue as well which is very strange... I am going through the entire click function okay but it's not clicking accept even though "Invoke pattern OK" is successful. This NPE.exe (norton power eraser) is really getting on my nerves lol.

Window handle OK
UI Automation object OK
Automation element from window OK
Accept condition OK
Invoke pattern OK
 
#include <CUIAutomation2.au3>
#RequireAdmin

MainFunc()

Func MainFunc()

    If ProcessExists("NPE.exe") = 0 Then
        ShellExecute("C:\temp\NPE.exe")
    EndIf

    Sleep(5000)

    WinWait("Norton Power Eraser")

    WinActivate("Norton Power Eraser")

    WinWaitActive("Norton Power Eraser")

    Sleep(5000)

    If WinExists("Norton Power Eraser") Then WinActivate("Norton Power Eraser")

    Local $hWindow = WinGetHandle("Norton Power Eraser")
    If Not $hWindow Then Return ConsoleWrite("Window handle ERR" & @CRLF)
    ConsoleWrite("Window handle OK" & @CRLF)

    ; Create UI Automation object
    Local $oUIAutomation = ObjCreateInterface($sCLSID_CUIAutomation, $sIID_IUIAutomation, $dtagIUIAutomation)
    If Not IsObj($oUIAutomation) Then Return ConsoleWrite("UI Automation object ERR" & @CRLF)
    ConsoleWrite("UI Automation object OK" & @CRLF)

    ; Get UI Automation element from window handle
    Local $pWindow, $oWindow
    $oUIAutomation.ElementFromHandle($hWindow, $pWindow)
    $oWindow = ObjCreateInterface($pWindow, $sIID_IUIAutomationElement, $dtagIUIAutomationElement)
    If Not IsObj($oWindow) Then Return ConsoleWrite("Automation element from window ERR" & @CRLF)
    ConsoleWrite("Automation element from window OK" & @CRLF)

    ; Condition to find "Accept" button
    Local $pCondition, $pCondition1, $pCondition2
    $oUIAutomation.CreatePropertyCondition($UIA_ControlTypePropertyId, $UIA_ButtonControlTypeId, $pCondition1)
    $oUIAutomation.CreatePropertyCondition($UIA_NamePropertyId, "Accept", $pCondition2)
    $oUIAutomation.CreateAndCondition($pCondition1, $pCondition2, $pCondition)
    If Not $pCondition Then Return ConsoleWrite("Accept condition ERR" & @CRLF)
    ConsoleWrite("Accept condition OK" & @CRLF)

    ; Find "Accept" button
    Local $pButton, $oButton
    $oWindow.FindFirst($TreeScope_Descendants, $pCondition, $pButton)
    $oButton = ObjCreateInterface($pButton, $sIID_IUIAutomationElement, $dtagIUIAutomationElement)

        ; Click (invoke) "Accept" button
    Local $pInvoke, $oInvoke
    $oButton.GetCurrentPattern($UIA_InvokePatternId, $pInvoke)
    $oInvoke = ObjCreateInterface($pInvoke, $sIID_IUIAutomationInvokePattern, $dtagIUIAutomationInvokePattern)
    If Not IsObj($oInvoke) Then Return ConsoleWrite("Invoke pattern ERR" & @CRLF)
    ConsoleWrite("Invoke pattern OK" & @CRLF)
    $oInvoke.Invoke()
    Sleep(2000)

EndFunc

Tried this one too...

AutoItSetOption("MustDeclareVars", 1)

Local $oP4=_UIA_getObjectByFindAll($UIA_oDesktop, "Title:=Norton Power Eraser;controltype:=UIA_PaneControlTypeId;class:=NortonPowerEraserWnd", $treescope_children)
_UIA_Action($oP4,"setfocus")
Local $oP3=_UIA_getObjectByFindAll($oP4, "Title:=;controltype:=UIA_CustomControlTypeId;class:=", $treescope_children)
Local $oP2=_UIA_getObjectByFindAll($oP3, "Title:=;controltype:=UIA_PaneControlTypeId;class:=", $treescope_children)
Local $oP1=_UIA_getObjectByFindAll($oP2, "Title:=;controltype:=UIA_PaneControlTypeId;class:=", $treescope_children)
Local $oP0=_UIA_getObjectByFindAll($oP1, "Title:=;controltype:=UIA_PaneControlTypeId;class:=", $treescope_children)
;~ First find the object in the parent before you can do something
;~$oUIElement=_UIA_getObjectByFindAll("Accept.mainwindow", "title:=Accept;ControlType:=UIA_ButtonControlTypeId", $treescope_subtree)
Local $oUIElement=_UIA_getObjectByFindAll($oP0, "title:=Accept;ControlType:=UIA_ButtonControlTypeId", $treescope_subtree)
_UIA_action($oUIElement,"click")

Here is the result from  inspect.exe

How found: Mouse move (818,560)
hwnd=0x00000000000A051E 32bit class="NortonPowerEraserWnd" style=0xFFFFFFFF960A0800 ex=0x40000
Name: "Accept"
ControlType: UIA_TextControlTypeId (0xC364)
LocalizedControlType: "text"
BoundingRectangle: {l:755 t:547 r:845 b:566}
 
or 
 
How found: Mouse move (803,706)
hwnd=0x00040BAA 32bit class="NortonPowerEraserWnd" style=0x960A0800 ex=0x40000
Name: "Accept"
ControlType: UIA_ButtonControlTypeId (0xC350)
LocalizedControlType: "button"
BoundingRectangle: {l:709 t:674 r:825 b:718}
 
Thanks again everyone!
Edited by souldjer777

"Maybe I'm on a road that ain't been paved yet. And maybe I see a sign that ain't been made yet"
Song Title: I guess you could say
Artist: Middle Class Rut

Share this post


Link to post
Share on other sites

Cant help with how your trying to do it, but I noticed you can take out the first Sleep() you have since you have WinWait() that will properly hold the script until the window is avalible. 

Share this post


Link to post
Share on other sites

alternative approach is counting back or forward from an element that has a title

so like

"title:=Scan for Risks; indexrelative:=-3"
"title:=Scan for Risks; indexrelative:=-4"

The framework is using findall that returns an array of elements

in uiawrappers you can reveal it within the parent element with this function

 
;~ Just dumps all information under a certain object
_UIA_DumpThemAll($oElementStart, $treeScope)

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

souldjer777, Try this:

 

#include <CUIAutomation2.au3>

Example()

Func Example()

  ; Get window handle
  Local $hWindow = WinGetHandle( "Norton Power Eraser" )
  If Not $hWindow Then Return ConsoleWrite( "Window handle ERR" & @CRLF )
  ConsoleWrite( "Window handle OK" & @CRLF )

  ; Create UI Automation object
  Local $oUIAutomation = ObjCreateInterface( $sCLSID_CUIAutomation, $sIID_IUIAutomation, $dtagIUIAutomation )
  If Not IsObj( $oUIAutomation ) Then Return ConsoleWrite( "UI Automation object ERR" & @CRLF )
  ConsoleWrite( "UI Automation object OK" & @CRLF )

  ; Get UI Automation element from window handle
  Local $pWindow, $oWindow
  $oUIAutomation.ElementFromHandle( $hWindow, $pWindow )
  $oWindow = ObjCreateInterface( $pWindow, $sIID_IUIAutomationElement, $dtagIUIAutomationElement )
  If Not IsObj( $oWindow ) Then Return ConsoleWrite( "Automation element from window ERR" & @CRLF )
  ConsoleWrite( "Automation element from window OK" & @CRLF )

  ; Condition to find a button
  Local $pCondition
  $oUIAutomation.CreatePropertyCondition( $UIA_ControlTypePropertyId, $UIA_ButtonControlTypeId, $pCondition )
  If Not $pCondition Then Return ConsoleWrite( "Find condition ERR" & @CRLF )
  ConsoleWrite( "Find condition OK" & @CRLF )

  ; Find all buttons
  Local $pUIElementArray, $oUIElementArray, $iElements
  $oWindow.FindAll( $TreeScope_Descendants, $pCondition, $pUIElementArray )
  $oUIElementArray = ObjCreateInterface( $pUIElementArray, $sIID_IUIAutomationElementArray, $dtagIUIAutomationElementArray )
  $oUIElementArray.Length( $iElements )
  If Not $iElements Then Return ConsoleWrite( "No objects found ERR" & @CRLF )
  ConsoleWrite( $iElements & " objects found OK" & @CRLF )

  ; Identify proper button by size
  ; (Post 1 in bold: ;177;177)
  Local $pUIElement, $oUIElement, $fIdentified = False, $s
  For $i = 0 To $iElements - 1
    $oUIElementArray.GetElement( $i, $pUIElement )
    $oUIElement = ObjCreateInterface( $pUIElement, $sIID_IUIAutomationElement, $dtagIUIAutomationElement )
    $s = _UIA_getPropertyValue( $oUIElement, $UIA_BoundingRectanglePropertyId )
    If StringInStr( $s, "; 177; 177" ) Then ; _UIA_getPropertyValue uses "; " instead of ";"
      ConsoleWrite( "Object identified OK" & @CRLF )
      $fIdentified = True
      ExitLoop
    EndIf
  Next
  If Not $fIdentified Then Return ConsoleWrite( "No object identified ERR" & @CRLF )

  ; Click button
  ConsoleWrite( "Trying to activate object ..." & @CRLF )
  Local $aPos = StringSplit( $s, "; ", 3 )
  MouseClick( "left", $aPos[0] + $aPos[2] / 2, $aPos[1] + $aPos[3] / 2 )

EndFunc


Func _UIA_getPropertyValue( $obj, $id )
  Local $tVal
  $obj.GetCurrentPropertyValue( $id, $tVal )
  If Not IsArray( $tVal ) Then Return $tVal
  Local $tStr = $tVal[0]
  For $i = 1 To UBound( $tVal ) - 1
    $tStr &= "; " & $tVal[$i]
  Next
  Return $tStr
EndFunc
Edited by LarsJ

Share this post


Link to post
Share on other sites

#12 ·  Posted (edited)

Could someone please try the script / exe on their own computer and let me know if it works? 

NPE.exe is Norton Power Eraser:
 
I've tried everything... invoking everything... I can't click on the accept...
 
I feel like an idiot - setting myself up here  :idiot:
Edited by souldjer777

"Maybe I'm on a road that ain't been paved yet. And maybe I see a sign that ain't been made yet"
Song Title: I guess you could say
Artist: Middle Class Rut

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0