Jump to content

ControlCommand / ControlClick Parameters not working


Recommended Posts

Hi,

my program does find the window (with a disabled button called "&Weiter >" which is german for "&continue >",

but in my Loop it keeps staying false, even once the button is enabled. any idea what i'm doing wrong here ?

 

regards,

malicor

 

autoit2.png

Edited by malicor
Link to comment
Share on other sites

Have you checked if your program has command line parameters to install automatically? It looks like you're setting up SQL Server 2016. If so, I would take a look here to see if what you want to do is possible silently :)https://docs.microsoft.com/de-de/sql/database-engine/install-windows/install-sql-server-from-the-command-prompt?view=sql-server-2016  <-- I attempted to get the german link too

All my code provided is Public Domain... but it may not work. ;) Use it, change it, break it, whatever you want.

Spoiler

My Humble Contributions:
Personal Function Documentation - A personal HelpFile for your functions
Acro.au3 UDF - Automating Acrobat Pro
ToDo Finder - Find #ToDo: lines in your scripts
UI-SimpleWrappers UDF - Use UI Automation more Simply-er
KeePass UDF - Automate KeePass, a password manager
InputBoxes - Simple Input boxes for various variable types

Link to comment
Share on other sites

On ‎10‎/‎2‎/‎2019 at 9:45 PM, seadoggie01 said:

Have you checked if your program has command line parameters to install automatically? It looks like you're setting up SQL Server 2016. If so, I would take a look here to see if what you want to do is possible silently :)https://docs.microsoft.com/de-de/sql/database-engine/install-windows/install-sql-server-from-the-command-prompt?view=sql-server-2016  <-- I attempted to get the german link too

and yes, i can try the silent install, but right now i'm more interested in trying to find out WHY the Control isn't found. it doesnt seem to make any sense to me

Link to comment
Share on other sites

from the look of those controls, you may need to use alternative methods. can you link me the installer--if it's an available one on the web, so i can test it in a vm?

 

also, your waiting logic isn't up to snuff. please post your script and not an image. use the CODE TAGS (the look like this <> and post your code in that so it's nicely formatted and colored and linked to help where appropriate)

Edited by Earthshine

My resources are limited. You must ask the right questions

 

Link to comment
Share on other sites

hi,

i'm trying to install the (german) Version of mssql Server 2016 express edition

https://www.microsoft.com/de-DE/download/details.aspx?id=56840

from what i read you would have to download that small online-installer, execute it and then save it as the offline variation

the file i m executing is named SQLEXPRADV_x64_DEU_SP2.exe and it's 1.520.851kB in size.

- - -

here the (interesting part of) the script i m trying to get to run:

the function _neueEigenstaendigeSQL() is just opening the real Installation window, and my Problem already appears in the very next step at _lizenzbedingungen()

 

#RequireAdmin
AutoItSetOption('MouseCoordMode', 0)
AutoItSetOption('SendKeyDelay', 350)

#include <primionHelper.au3>

; --- about ---
; installs MSSQL 2016 Express Edition (EE) to "C:\Programme (x86)\Microsoft SQL Server"
; --- /about ---

; --- preparation ---
;
; the file "C:\downloads\SQLEXPRADV_x64_DEU_SP2.EXE" must be executed once by hand to extract
; all installation files. (This could later on easily be integrated into this script if preferred,
; or otherwise maybe handled by the copy-job (copyInstallers-161.1.bat)
;
; --- /preparation ---

; --- uninstall ---
; uninstall via WINDOWS->Programme hinzufügen oder entfernen->"Microsoft SQL Server 2016 (64-bit)"
; this will remove some of the other components listed there, too.
; --- /uninstall ---

; --- configuration ---
$installationFile = "C:\downloads\SQLEXPRADV_x64_DEU_SP2\SETUP.EXE"
; --- /configuration ---

; --- script ---
;Run($installationFile)

;_neueEigenstaendigeSQL()
_lizenzbedingungen()
;~ _microsoftUpdate()
;~ ;_produktUpdates()
;~ _installationsregeln()
;~ _expressFunktionen()
;~ _nameInstanz()
;~ _dienstkonten()
;~ _authentifizierung()
;~ _installationAbgeschlossen()
;~ _closeWindow()
_Debug("...end")
Sleep(8000)
; --- /script ---


; --- functions ---
Func _neueEigenstaendigeSQL()
   Do
      Sleep(500)
   Until _WinWaitActivate("SQL Server-Installationscenter", "Neue eigenständige SQL")

   _Send("{TAB}{ENTER}")
EndFunc


Func _lizenzbedingungen()
   Do
      Sleep(500)
   Until _WinWaitActivate("SQL Server 2016-Setup", "Lizenzbedingungen")
   _Send("{SPACE}")

   Local $result
   Local $text = "&Weiter >"
   Do
      _Debug("waiting for enabled...")
      ;$result = ControlCommand("SQL Server 2016-Setup", "", "[CLASS:Button; TEXT:" & $text & "; INSTANCE:2]", "IsEnabled")
      $result = ControlCommand("SQL Server 2016-Setup", "", "[ID:722632]", "IsEnabled")

      _Debug("text: -->" & ControlGetText("SQL Server 2016-Setup", "", 722632) & "<--")
      _Debug("error:" & @error)
      _Debug("..." & $result)
      Sleep(500)
   Until $result

   ;Until _ControlClick("SQL Server 2016-Setup", "Lizenzbedingungen", "[ID:1967548]", "left")
   ;_ControlSend("SQL Server 2016-Setup", "Lizenzbedingungen", "[CLASS:Button; TEXT:Weiter]", "{ENTER}")
   ;Send("!+w")

;~    Do
;~    Sleep(500)
;~    Until _ControlClick("SQL Server 2016-Setup", "Lizenzbedingungen", "[CLASS:Button; TEXT:Weiter; INSTANCE:2]", "left")
EndFunc

it doesn't work with the id (i still get @error == 1) and additionally to that the id changes everytime i restart the whole thing

the next Code is the complete file primionHelper.au3:

 

#RequireAdmin

#include <MsgBoxConstants.au3> ; only required for MsgBox constants
#include <Misc.au3>
#include <FileConstants.au3>

Local $hDLL = DllOpen("user32.dll")

Global $Paused
Global $debugOutput = ""

HotKeySet("{F3}", "TogglePause")
HotKeySet("{ESC}", "Terminate")

; --- functions ---

; used to write a debug message to the top left of the screen
; @text - the text that shall be output, preceed with [DEBUG] for info about the code or [PROGRESS] for info about the process status
Func _Debug($text)
    $debugOutput = $debugOutput & @CRLF & $text
    ToolTip($debugOutput, 50, 50, "DEBUG-OUTPUT")
EndFunc


; wait for a window to be loaded, shown and make it active, retry until success
;
; use the program "AutoIt v3 Window Info" to figure out @title and @text
;
; @title - the title of the window (autoIt: >>>> Window <<<< Title)
; @text - a substring of the text that appears somewhere in the window (autoIt: >>>> Visible Text <<<<)
; @timeout - wait for this many seconds for the (at the moment inactive) window to get active
;
; @RETURNS - 0, if the window isn't found and active yet
;            1, else
Func _WinWaitActivate($title, $text, $timeout = 3)
   If Not WinWaitActive($title, $text, 3) Then
      _Debug("[DEBUG] waiting for window: title: -->" & $title & "<-- text: -->" & $text & "<--, found yet? -> FALSE" )
      Return 0
   Else
      _Debug("[DEBUG] waiting for window: title: -->" & $title & "<-- text: -->" & $text & "<--, found yet? -> TRUE" )
      Return 1
   EndIf

   WinWait($title, $text, $timeout)
   If Not WinActive($title, $text) Then WinActivate($title, $text)
EndFunc   ;==>_WinWaitActivate


; send keys directly to a control element
;
; use the program "AutoIt v3 Window Info" to figure out @title and @text etc.
;
; @title - the title of the window (autoIt: >>>> Window <<<< Title)
; @text - a substring of the text that appears somewhere in the window (autoIt: >>>> Visible Text <<<<)
; @controlId - control element as defined by autoIt (check autoIt help for "Controls" for details)
; @what - the keys to send to the control element
;
; @RETURNS - 0, if the window isn't found and active yet
;            1, else
Func _ControlSend($title, $text, $controlId, $what)
   Local $result = ControlSend($title, $text, $controlId, $what)
   _Debug("[DEBUG] ControlSend: title: -->" & $title & "<-- text: -->" & $text & "<-- controlId: -->" & $controlId & "<-- what: -->" & $what & "<--, result: -> " & $result & "<--")
EndFunc


; send keys directly to a control element
;
; use the program "AutoIt v3 Window Info" to figure out @title and @text etc.
;
; @title - the title of the window (autoIt: >>>> Window <<<< Title)
; @text - a substring of the text that appears somewhere in the window (autoIt: >>>> Visible Text <<<<)
; @controlId - control element as defined by autoIt (check autoIt help for "Controls" for details)
; @what - the keys to send to the control element
;
; @RETURNS - 0, if the window isn't found and active yet
;            1, else
Func _ControlClick($title, $text, $controlId, $button)
    Local $result = ControlClick($title, $text, $controlId, $button)
   _Debug("[DEBUG] _ControlClick: title: -->" & $title & "<-- text: -->" & $text & "<-- controlId: -->" & $controlId & "<-- button: -->" & $button & "<-- result: -->" & $result & "<--")
EndFunc


Func _Send($text)
   _Debug("[DEBUG] Sending: " & $text);
   Send($text)
EndFunc


; pause or unpause the script by pressing "F3"
Func TogglePause()
   $Paused = NOT $Paused
   While $Paused
      sleep(100)
   WEnd
EndFunc


; end the script by pressing "ESC"
Func Terminate()
   Exit 0
EndFunc


; wait until "F2" is pressed
Func _WaitUntilKeyPressed()
   Do
      Sleep(100)
   Until _IsPressed("{F2}", $hDLL)
EndFunc
; --- /functions ---

i'm still at the very beginning of learning autoIt so my waiting/Control commands are quite probably not the best way to do it, if there's smarter ways help would be greatly appreciated

 

Link to comment
Share on other sites

2 hours ago, malicor said:

<snip>  if there's smarter ways help would be greatly appreciated

Honestly, yes. I wouldn't try to automate something if it's already been done or can be done differently. I think part of automating something is learning what needs to be automated. If your script was building command line parameters and executing the program silently, then I'd be all for that. This just seems silly unless there is something you can do with the gui that you can't with the command line. Messing with GUIs is much harder than setting some command line options. I think this sounds angrier than I meant, my apologies if it comes across that way, it wasn't intended to :)

If you need the GUI, however, and the ID of the button keeps changing, try playing with some of the other controls options (see here). You might be able to get away with saying "[CLASS:Button; INSTANCE:1]" or something similar. Otherwise, you might need to build a regular expression to get the class name. Something like "[REGEXPCLASS:WinForms\.10\.BUTTON.*]" might work. 

All my code provided is Public Domain... but it may not work. ;) Use it, change it, break it, whatever you want.

Spoiler

My Humble Contributions:
Personal Function Documentation - A personal HelpFile for your functions
Acro.au3 UDF - Automating Acrobat Pro
ToDo Finder - Find #ToDo: lines in your scripts
UI-SimpleWrappers UDF - Use UI Automation more Simply-er
KeePass UDF - Automate KeePass, a password manager
InputBoxes - Simple Input boxes for various variable types

Link to comment
Share on other sites

i can't get it with CLASS:Button or with a REGEXPCLASS ... due to some to me unknown reason the button simply is not found

Local $result
   Local $text = "&Weiter >"
   Do
      _Debug("waiting for enabled...")
      ;$result = ControlCommand("SQL Server 2016-Setup", "", "[CLASS:Button; TEXT:" & $text & "; INSTANCE:2]", "IsEnabled")
      $result = ControlCommand("SQL Server 2016-Setup", "", "[REGEXPCLASS:BUTTON.*; INSTANCE:1]", "IsEnabled")
      _Debug("result: -->" & $result & "<--")
      _Debug("error controlcommand:" & @error)

      ControlClick("SQL Server 2016-Setup", "", "[REGEXPCLASS:WindowsForms10\.BUTTON.*; INSTANCE:1]")
      _Debug("error controlclick:" & @error)

      Sleep(2000)
   Until $result

everything is 0 now, $result is 0, and both @error are 0

still the click is not executed, nothing happens (instance 1 is "cancel", but cancel is not clicked)

 

any idea why?

Link to comment
Share on other sites

so, the newer installers are not like the old ones that use a dialog that can easily be manipulated by AutoIt. This appears to be a newer type of form used, WPF I believe. so, you need to look at alternative methods of control. I doubt you will ever get this running as is.

 

look at FAQ 31 under UIAutomation

My resources are limited. You must ask the right questions

 

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...