Jump to content

ControlSend not affecting MSI dialog box


Recommended Posts

Bit of a noob here, but trying to learn. 

I have a driver that I'm trying to automate the installation of (Attunity Oracle Connector for Windows)  on Win2k12R2 and due to some apparent unorthodox coding within the package, a dialog box is presented prior to completion (and not suppressed by /quiet, but that's another argument for another day).  I'm trying to interact with the dialog box and select 'NO'  with AutoIT. 

Here's the code I have:
 

Local $handle=WinWait("Microsoft Connector for Oracle by Attunity","You should restart the SQL Server Integration Service",600)
ConsoleWrite($handle & @LF)
sleep(3000)

$results=ControlSend($handle, "", "Button2", "n")
ConsoleWrite("ControlSend: "& $results & @LF)

I'm writing the handle value out, and it is returning the correct handle. I even went as far as using WinActivate($handle) and the window became active. So, the value is good. ControlSend returns with a value of 1, so it seems to have sent the message to the window. 

For the ControlSend ControlID value, I have tried the controlID of 7, "Button2" and even [CLASS:Button; INSTANCE:2]. All with the same results. 

I also tried WinWaitActive() and Send() without luck. ControlClick(), WinClose() and WinKill() don't seem to affect the popup either, so I'm guessing the real issue has something to do with access (or something equally simple). I'm running both the MSI and script as admin. 

At this point, I'm thinking it is something really simple I'm missing. I've been pouring over documentation and the forums,  any ideas? 

Here's the summary from Au3Info for this particular popup:

Spoiler

>>>> Window <<<<
Title:    Microsoft Connector for Oracle by Attunity
Class:    #32770
Position:    1345, 792
Size:    532, 230
Style:    0x94C801C5
ExStyle:    0x00010101
Handle:    0x00000000001C0618

>>>> Control <<<<
Class:    Button
Instance:    2
ClassnameNN:    Button2
Name:    
Advanced (Class):    [CLASS:Button; INSTANCE:2]
ID:    7
Text:    &No
Position:    418, 143
Size:    100, 35
ControlClick Coords:    54, 24
Style:    0x50010000
ExStyle:    0x00000004
Handle:    0x00000000001706CA

>>>> Mouse <<<<
Position:    1820, 991
Cursor ID:    0
Color:    0xDDDDDD

>>>> StatusBar <<<<

>>>> ToolsBar <<<<

>>>> Visible Text <<<<
&Yes
&No
You should restart the SQL Server Integration Services service before you begin working with the Connector.
Do you want setup to restart the service?


>>>> Hidden Text <<<<
 

 

Link to comment
Share on other sites

You'd think so....but this particular install seems to have some CustomAction that triggers the popup.  I've tried with /quiet, /qn and even with the log flags to see if that would suppress the popup.  I did a bit of digging with Orca to see if I could figure a way to bypass the popup, haven't figured that one out yet either. 

If you want to try to recreate, I'm on Win2k12R2 with SQL2014 installed. The driver is v3.0 for Attunity Oracle Connector. 

Link to comment
Share on other sites

thanks. I'll check it

well, it looks like it works, but I don't have Oracle or SQL server installed in my test VM

msiexec -i AttunitySSISOraAdaptersSetupX64.msi /qn

if not

ControlSend ("[CLASS:#32770]", "Microsoft Connector for Oracle by Attunity", "[CLASS:Button; INSTANCE:2]", "n")

however, you will most likely have to wait for it to exist. The installer goes about it's business until that thing, or series of dialogs pop up.

Edited by Earthshine

My resources are limited. You must ask the right questions

 

Link to comment
Share on other sites

Thanks for trying to reproduce, I think the kicker is that SQL isn't present on your test server. The popup is requesting to restart a service that is part of SQL. Without the presence of that service, the popup probably isn't presented. Though if the drivers are installed prior to SQL, I doubt the drivers would be registered and available within SQL.  

I'm still trying some different approaches. Right now, I have the popup present and using SciTE to throw scripts at it in hopes something works. 

Link to comment
Share on other sites

Unfortunately not. The popup still persists. 

Though, your example did interest me. I thought ControlSend() was  "title", "window text", controlID, "string to send".  The title value set to a CLASS makes sense, but why would you put the title string into the 'window text' field? 

Link to comment
Share on other sites

  • Developers

Are you sure you are running with the same (admin) level? -> tried adding #RequireAdmin at the tip of the script?

Jos

Edited by Jos
Fixed typo

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

is it #RequireAdmin or @RequireAdmin?  

I tried with #RequireAdmin, thinking along the same lines. I'm also initiating the driver install from an admin powershell session. 

I still think it's a rights issue, just not sure how to check or force it. 

Link to comment
Share on other sites

Had a thought to call the install in the script, reasoning that should force both the install and script to run at the same level. 

#RequireAdmin
ShellExecute("msiexec", '/i C:\Temp\AttunitySSISOraAdaptersSetupX64.msi /qn')

Local $handle=WinWait("Microsoft Connector for Oracle by Attunity","You should restart the SQL Server Integration Service",600)
ConsoleWrite($handle & @LF)
sleep(3000)

$result=ControlSend($handle, "", "Button2", "n")
ConsoleWrite("ControlSend: "& $result & @LF)

Getting the same results of this popup. After the popup appears, the script appropriately outputs the handle information and closes. 

I'm starting to wonder if msiexec is handing off the install to SYSTEM, and that is preventing the script from pushing input to the window. (Sounds crazy, but I'm running out of ideas)

Link to comment
Share on other sites

Tried both  "&N" and "!N" with the same results. 

At first I mistyped the controlID as "button2" and the ControlSend command returned 0 (fail). Correcting it to "Button2" puts me back to a return of 1 (success), so that leads me to believe the script is seeing and attempting to interact with the correct element. 

Link to comment
Share on other sites

Went back to basics and tried Mouseclick("Right", x , y) and that didn't even work. I'm starting to question if there's something up with my test system. Like some obscure hotfix or setting that's preventing interaction with a CLASS:#32770 dialog box.  

I didn't see anything in the FAQs or docs, though I there doesn't seem to be a shortage of threads dealing with this particular class of dialog without solution. Though that could just be from a lack of followup by OPs if something works. 

Link to comment
Share on other sites

If you implement some logging and you need to do some looping to make sure you are going to talk to the control with control text = "&No" first, that might help. I did it like this using log4a.au3 (found on this forum)

#include-once
#include <Timers.au3>
#include "log4a.au3"

; #FUNCTION# ====================================================================================================================
; Name ..........: _checkClickCtrl
; Description ...: Automatically wait for a control to exist. Forever or Limited
; Syntax ........: _checkClickCtrl($formclass, $text, $ctrl, $ctrltxt, $timeout, $delayafter
; Parameters ....: $formclass           - Form Class info.
;                  $text                - Windows text to match
;                  $ctrl                - Class of Copntrol
;                  $ctrltxt             - Text of the Control
;                  $timeout             - Timeout = 0 by default, millisecond timer
;                  $delayafter          - Time in milliseconds to delay after operation carried out
; Return values .: None
; Author ........: Earthshine
; Modified ......:
; Remarks .......:  Waits for each button indefinatly, unless you give it a timeout
;                   Logger found here: https://www.autoitscript.com/forum/topic/156196-log4a-a-logging-udf/
; Related .......:
; Link ..........:
; Example(s) ....:  _checkClickCtrl ('[CLASS:#32770]', 'ApplicationX - InstallShield Wizard', '[CLASS:Button; INSTANCE:1]', , '&Next >' 5000, 0)
;                   _checkClickCtrl($formclass, $text, $button2, $TD_BTN_REMOVE, 0, 0)
;                   _checkClickCtrl($formclass, $text, $button3, $TD_BTN_NEXT, 0, 500)
;                   _checkClickCtrl($formclass, $text, $button1, $TD_BTN_YES, 0, 0)
;                   _checkClickCtrl($formclass, $text, $button4, $TD_BTN_FINISH, 0, 0)
; ===============================================================================================================================
Func _checkClickCtrl($formclass, $text, $ctrl, $ctrltxt, $timeout = 0, $delayafter = 0)
    _log4a_Info("_checkClickCtrl():Begin")
    _log4a_Info("Searching for Formclass: " & $formclass)
    _log4a_Info("Searching for Text: " & $text)
    _log4a_Info("Searching for Control: " & $ctrl)
    _log4a_Info("Searching for Ctrl Txt: " & $ctrltxt)
    _log4a_Info("Timeout: " & $timeout)
    _log4a_Info("Time Delay (after click): " & $delayafter)
    Local $time_run = _Timer_Init()
    While (1)
        If WinExists($formclass) Then
            Local $hCtrl = ControlGetHandle($text, '', $ctrl)
            If $hCtrl Then
                If ($timeout > 0) Then
                    _log4a_Info(_Timer_Diff($time_run))
                    If (_Timer_Diff($time_run) > $timeout) Then
                        _log4a_Info("ExitLoop:Timeout - " & $ctrl)
                        ExitLoop
                    EndIf
                EndIf
                Local $hCtrlHandle = ControlGetText($text, '', $ctrl)
                _log4a_Info("Control Text Search: " & $ctrltxt)
                _log4a_Info("Control Text Found: " & $hCtrlHandle)
                If ($hCtrlHandle == $ctrltxt) Then
                    ; we got the handle, so the button is there
                    ; now do whatever you need to do
                    _log4a_Info("Found Formclass: " & $formclass)
                    _log4a_Info("Found Text: " & $text)
                    _log4a_Info("Found Control: " & $ctrl)
                    _log4a_Info("Found Ctrl Txt: " & $ctrltxt)
                    _log4a_Info("Timeout: " & $timeout)
                    _log4a_Info("Time Delay (after click): " & $delayafter)
                    _log4a_Info($ctrl)
                    ControlClick($formclass, '', $ctrl)
                    If ($delayafter > 0) Then
                        Sleep($delayafter)
                    EndIf
                    _log4a_Info("ExitLoop:Normal - " & $ctrl)
                    ExitLoop
                EndIf
            EndIf
        EndIf
    WEnd
    _log4a_Info("_checkClickCtrl():End")
EndFunc   ;==>_checkClickCtrl

Notice, I make darn sure I am talking to the right control before issuing a click. If you need help setting up log4a let me know, else just change all the _log4a calls to ConsoleWrite calls. this proved very reliable for me. setting up log4a from your main script is EASY

#include 'log4a.au3'


#Region ;**** Logging ****
; Enable logging and don't write to stderr
_log4a_SetEnable()
; Write to stderr, set min level to warn, customize message format
_log4a_SetErrorStream()
_log4a_SetCompiledOutput($LOG4A_OUTPUT_FILE)
_log4a_SetMinLevel($LOG4A_LEVEL_DEBUG)
; If @compiled Then _log4a_SetMinLevel($LOG4A_LEVEL_WARN) ; Change the min level if the script is compiled
_log4a_SetFormat("${date} | ${host} | ${level} | ${message}")
#EndRegion ;**** Logging ****

 

log4a.au3

Edited by Earthshine

My resources are limited. You must ask the right questions

 

Link to comment
Share on other sites

quick update, I did get it working! I ended up creating a test server on the enterprise domain and it worked right away, my initial test server was just a local VM with local accounts. The only difference I can tell is the executing account was a domain account when the script worked (though there could have been a GPO setting pushed down or a KB installed that was the fix). 

So, thanks to all for the help! That was the first part of the problem. I'm now working on putting this into puppet to deploy the automation and have a new problem. Since puppet runs as SYSTEM on the endpoint, that means the execution is happening in session 0. From what I can tell, session 0 gets a little tricky when trying to query and interact with GUI objects. Think I'm going to have to wrap everything in a script to run as a local account to get out of session 0, which would successfully execute the rest of the process and then let puppet manage the deletion of the temp local account. 

I didn't suspect a single driver would cause so much aggravation and work :) Hopefully this helps others who run into similar scenarios. 

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...