Jump to content

Can't control a window


Paradox
 Share

Recommended Posts

Hi, I'm kind of a n00b to the whole AutoIT realm. For almost the last 2 weeks, I've been working on an automation script that reads from an INI file, and spits out the information to the actual installer application. I've had great success with it thus far, however I'm running into a real bugger of a problem.

The installer program that I'm automating opens up one master window which can be seen in the taskbar, other 'sub-windows' which are not shown on the task bar. This isn't the part that's gotten me, it's just some background info... What's halted my progress is the installer will get to a specific spot (namely the "Setup Complete" portion) however, I've tried just about every thing to continue through this part... damn thing just won't go... I've done WinWait(), WinWaitActive() (with and without the title and/or text from the window), but no dice...

What really gets me is that the Windows Info Tool will tell me the title is "Setup Complete" (without quotes) and all the other info, however it seems as though AutoIT can't control it... I've even included Opt("WinSearchChildren", 1) into the code just incase that window is considered a child window, but again... nothing... It seems as though my only recourse for this is perhaps to add a Sleep(5000) or something to my code to get it to proceed..

Other than using Sleep, anyone have any ideas??? I'll submit my code if you want, just let me know...

Thanks!!

-J

Link to comment
Share on other sites

Okay, here goes, just bear with me on this:

#include <GUIConstants.au3>

; Declaration of Installation variables
global $name, $company, $serial, $dbserver_name, $dbdomain, $port, $srvpath, $basket_loc
global $clfolder, $scripts, $root, $websrv, $nt, $basket


;Variables are read in from .ini file
;Constants - Variables that will be used multiple times during the installation.
  $name = iniread("dbinstall.ini", "Constants", "Name", "not found")
  $company = iniread("dbinstall.ini", "Constants", "Company", "")
  $serial = iniread("dbinstall.ini", "Constants", "Serial", "")
  $dbserver_name = iniread("dbinstall.ini", "Constants", "DBServer_name", "")
  $dbdomain = iniread("dbinstall.ini", "Constants", "DBDomain_name", "")
  $port = iniread("dbinstall.ini", "Constants", "Basket_port", "")

;Server Install Info - Information that will be used only once during the
;installation of the Docubase Server application.
  $srvpath = iniread("dbinstall.ini", "Server_install_info", "Install_path", "")
  $basket_loc = iniread("dbinstall.ini", "Server_install_info", "Basket_location", "")
  $srvfolder = iniread("dbinstall.ini", "Server_install_info", "Program_folder", "")
 
;Client Install Info - Information that will be used only once during the
;installation of the Docubase Client application
  $clientpath = iniread("dbinstall.ini", "Client_install_info", "Install_path", "")
  $basket_srv = iniread("dbinstall.ini", "Client_install_info", "Basket_server", "")
  $clfolder = iniread("dbinstall.ini", "Client_install_info", "Program_folder", "")
 
;Web Retrieval Info - Used during the installation of the Web Retrieval Application
  $scripts = iniread("dbinstall.ini", "Web_retrieval", "Scripts_location", "")
  $root = iniread("dbinstall.ini", "Web_retrieval", "Documents_root_location", "")
  $websrv = iniread("dbinstall.ini", "Web_retrieval", "Server_name", "")
  $nt = iniread("dbinstall.ini", "Web_retrieval", "NT_Unix", "")


; End declaration of variables

; create opening GUI Control


 opt("GUIOnEventMode", 1)
 opt("WinSearchChildren", 1)
 
 GUICreate ("Install Method", 300, 200)
 GUICtrlCreateLabel("Please choose the installation method used for this session.", 10, 10)
 GUISetOnEvent($GUI_EVENT_CLOSE, "exit_app")
 $server=GUICtrlCreateButton("Server", 120, 40, 80)
 $client=GUICtrlCreateButton("Client", 120, 80, 80)
 $web=GUICtrlCreateButton("Web Retrival", 120, 120, 80)
 $exit=guictrlcreatebutton("Exit Install", 120, 160, 80)
 GUICtrlSetOnEvent($server, "Server_install")
 GUICtrlSetOnEvent($client, "client_install")
 guictrlsetonevent($web, "Web_install")
 guictrlsetonevent($exit, "exit_app")
 GUISetState (@SW_SHOW)


 func Server_install()
  opt("WinSearchChildren", 1)
  run("..\server\setup.exe")
  
  winwaitactive("Welcome")
   send("{ENTER}")
 
  winwaitactive("Software License Agreement")
   send("{enter}")
  
  winwaitactive("User Information")
   send($name & "{TAB}" & $company & "{TAB}" & $serial & "{enter}")

  if winwaitactive("Choose Destination Location")=1 then
   send("!R")
  endif

  winwaitactive("Choose Folder")
   send($srvpath & "{enter}")
    if winwaitactive("Setup", "", 2)=1 then
     send("{enter}")
    endif
  send("!N")

  WinWaitactive("Select Components")
   Send("{enter}")

  winwaitactive("Server network choice")
   send($dbserver_name & "{tab}" & $dbdomain & "{enter}")

  
;Waits to see if the Docubase Baskets Server will appear before continuing...
  if winwaitactive("Docubase baskets server name identification.", "", 3)=1 then
   $basket=1
   send("!R")
   winwaitactive("Choose Folder")
    send($basket_loc & "{enter}")
    send("!N")
   winwaitactive("Port Determination")
    send($port & "{enter}")
  endif

  winwaitactive("Select Program Folder")
   send($srvfolder & "{enter}")

  winwaitactive("Options")
   send("{DOWN}")
   send("{space}")
    if $basket=1 then
     send("{DOWN}")
     send("{space}")
    endif
   send("{enter}")

  winwaitactive("Registry Editor")
   send("!Y")
  winwaitactive("Registry Editor")
  winwaitactive("Registry Editor")
   send("{ENTER}")
  winwaitclose("Registry Editor")
  

  if winwaitactive("Registry Editor")=1 then
   send("!Y")
   sleep(100)
   send("{ENTER}")
   winwaitclose("Registry Editor")
  endif

  winwaitactive("Setup Complete")
   send("{ENTER}")

  winwaitactive("Information")
  send("{enter}")

  winwaitclose("Docubase Systems")

EndFunc

;end server installation

Told you it was lengthy...

As far as the installer name, I really don't think it would help you guys out that much... It's a self-developed program for the company I work for: Docubase Systems, Inc. We do document management and write our own apps. But if you mean what did the developers use for the installer, I believe it's InstallShield or something like that... Hope this helps out! Thanks man!

Link to comment
Share on other sites

maybe try something like this...( you need to fill in the info)

you should read more about this in help

While 1
    If ControlCommand("Setup Complete", "???text???", 2, "IsEnabled", "") Then ExitLoop
WEnd


ControlFocus("Setup Complete", "???text???", 2)
ControlClick("Setup Complete", "???text???", 2, "left", 1)

again you may need to read more about this in help... this is an example/idea

hope that helps

8)

NEWHeader1.png

Link to comment
Share on other sites

maybe try something like this...( you need to fill in the info)

you should read more about this in help

While 1
    If ControlCommand("Setup Complete", "???text???", 2, "IsEnabled", "") Then ExitLoop
WEnd
ControlFocus("Setup Complete", "???text???", 2)
ControlClick("Setup Complete", "???text???", 2, "left", 1)

<{POST_SNAPBACK}>

To be honest with you, the controlID thing has me a little confused. when you're saying "..."???text???", 2,...." I know the 'text' section is referring to the text that's in the window, but what is the signifigance of the 2?

I used the Window Info tool and looked up the ControlID of the window in question (which is 32770), however, that's the same controlID for ALL of the parent windows that are spawned during the installation.

Thanks though for the suggestion, I'll be sure to give it a whack during my coding today!

Link to comment
Share on other sites

  • Moderators

ControlID of the window in question (which is 32770)

That looks like the Class to me, not the control ID. Look further down the AutoInfo tool.

You should see something like this (Used MS-Paint for the example):

>>>>>>>>>>> Control Under Mouse <<<<<<<<<<<

Size:  X: -2    Y: 840    W: 259    H: 51

Control ID: 59416

ClassNameNN: AfxWnd42u1

Text:  Colors

See the text there, that's what Vaulter was talking about.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

Welcome to the forums!

From what I understand, your script seems to stop responding at the Setup Complete box. It's possible that the window just isn't getting focus when it appears. Try this:

winWait("Setup Complete")
winActivate("Setup Complete")
winWaitActive("Setup Complete")

This is always a safer method of waiting for a window since there's always a reason why a window might not focus when it opens, e.g. if your installer had just installed something via a silent-ish third-party executable.

If not, then there is the slight possibility that the 'Setup Complete' caption actually contains an extra space at the beginning: ' Setup Complete'. This will show subtly in AutoIt's Window Info if so.

If you're not 100% sure that this is where the problem lies, you could try adding a debugging MsgBox() on each side of the WinWait() command.

Link to comment
Share on other sites

See the text there, that's what Vaulter was talking about.

<{POST_SNAPBACK}>

Oops... my bad, your right.. that is the class (the 32770) dur...

here's a full copy & paste from the window tool on the window in question with the mouse on the 'finish' button.

Press CTRL-ALT-F to pause the display.

>>>>>>>>>>>> Window Details <<<<<<<<<<<<<
Title:  Setup Complete
Class:  #32770
Size:   X: 272  Y: 202  W: 479  H: 364

>>>>>>>>>>> Mouse Details <<<<<<<<<<<
Window: X: 349  Y: 347
Cursor ID:  2

>>>>>>>>>>> Pixel Color Under Mouse <<<<<<<<<<<
RGB:    Hex: 0xECE9D8   Dec: 15526360

>>>>>>>>>>> Control Under Mouse <<<<<<<<<<<
Size:       X: 296  Y: 301  W: 75   H: 23
Control ID: 1
ClassNameNN:    Button5
Text:       Finish
Style:      0x50010001
ExStyle:        0x00000004

>>>>>>>>>>> Status Bar Text <<<<<<<<<<<


>>>>>>>>>>> Visible Window Text <<<<<<<<<<<
Yes, I want to restart my computer now.
No, I will restart my computer later.
< &Back
Finish
Setup has finished copying files to your computer. 

Before you can use the program, you must restart Windows or your computer.
Remove any disks from their drives, and then click Finish to complete setup.
CutWinName
@10551

>>>>>>>>>>> Hidden Window Text <<<<<<<<<<<
Yes, I want to restart Windows now.
@10550,10551;1;1;0,128,128;0,128,128

Now here's the funny part for me. I've read the docs for using the the controlID in my code, (and the hint that Valuator left).. but I still feel slightly lost. When I'm specifying that I want the Finish button to be pressed, do I have to refer to in in the "???text???" portion that Valuator suggested???

Thanks guys!

Link to comment
Share on other sites

winWait("Setup Complete")
winActivate("Setup Complete")
winWaitActive("Setup Complete")
Wouldn't I be just giving it basically the same command twice??? Yeah, winWait() would wait for the window, but so would winActivate(), and winWaitActive() would do the same thing as all 3.... right???

This is always a safer method of waiting for a window since there's always a reason why a window might not focus when it opens, e.g. if your installer had just installed something via a silent-ish third-party executable.

Nah... no 3rd party executable. This is software that's written completely in house. If anything, right now *I* am the 3rd party. The window is focused when it appears, it just sits there during my winwaitactive("Setup Complete") call.

As far as an extra space in front of the Setup Complete title... I took a look at it, and I can't see one.

I'll have to try the MsgBox() debug though... maybe I'll find something out that way...

Thanks for the tip!

Link to comment
Share on other sites

  • Moderators

ControlFocus("Setup Complete", "Finish", "Button5")

ControlClick("Setup Complete", "Finish", "Button5", "left", 1)

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

<{POST_SNAPBACK}>

Ohhhhh... I get it now... The docs say "text" and the way I'm reading it, I'm thinking that it's referring to the dialog text in the window, not the text of the control that I want to use!!! I feel like such a tool now... ;)

Thanks Ron, I'll jump right on that one dude... !!

Let ya know how it goes!

Link to comment
Share on other sites

<{POST_SNAPBACK}>

Nah man, no dice... Still just sits there... I even modified the code that both you and Valuator suggested to:

While 1
    If Controlcommand("Setup Complete", "Finish", 1, "IsVisible", "") Then exitloop
   wend

   ControlFocus("Setup Complete", "Finish", 1)
   ControlClick("Setup Complete", "Finish", 1, "left", 1)

but still nothing. I figured with the "IsVisible" rather that "IsEnabled (which didn't work either) it would check to see if the button was even there rather than see if it's enabled for usage...

ARGH!!!!

Link to comment
Share on other sites

  • Moderators

Try this:

Opt("WinTitleMatchMode", 2)

While 1
   If WinExists("Setup Complete") Then 
      MsgBox(0, "Setup Exists", "It Exists and I'm Reading It")
      ControlClick("Setup Complete", "Finish", 1, "left", 1)
   EndIf
; Rest of Script
Wend

Edit: Forgot Code Tags

Edit2: I haven't looked at your script ;) ... I'll take a look at that (I was only trying to explain the Control()'s to you.

Edited by ronsrules

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

Woo-hoo!!! Figured it out!!! If you look back at my original code, I had

if winwaitactive("Registry Editor")=1 then
   send("!Y")
   sleep(100)
   send("{ENTER}")
   winwaitclose("Registry Editor")
  endif

immediately before the WinWaitActive("Setup Complete") procedure. Everything that I had with that particular WinWaitActive() call, it was the If WinWaitActive("Registry Editor")=1 that was screwing me up. The way I had it written it's WAITING for the window to appear when they're a possibility that it won't (dependant on installer package). I changed it to:

If WinExists("Registry Editor") Then
and just to prove that the "Setup Complete" window was visible I threw in a If..Else..Endif MsgBox() procedure telling me the window is there!!!

Thanks guys!!! You all may not have given me the answer, but you made me rethink what I had written. Thank you thank you thank you!

Oh, and the ControlCommand, ControlFocus, and ControlClick functions worked out great with it too!

Edited by Paradox
Link to comment
Share on other sites

Woo-hoo!!! Figured it out!!! If you look back at my original code, I had

if winwaitactive("Registry Editor")=1 then
   send("!Y")
   sleep(100)
   send("{ENTER}")
   winwaitclose("Registry Editor")
  endif

immediately before the WinWaitActive("Setup Complete") procedure. Everything that I had with that particular WinWaitActive() call, it was the If WinWaitActive("Registry Editor")=1 that was screwing me up. The way I had it written it's WAITING for the window to appear when they're a possibility that it won't (dependant on installer package). I changed it to:

If WinExists("Registry Editor") Then
and just to prove that the "Setup Complete" window was visible I threw in a If..Else..Endif MsgBox() procedure telling me the window is there!!!

Thanks guys!!! You all may not have given me the answer, but you made me rethink what I had written. Thank you thank you thank you!

Oh, and the ControlCommand, ControlFocus, and ControlClick functions worked out great with it too!

<{POST_SNAPBACK}>

glad you got it working, and thanks for posting the actual issue and resolution once you found it, that definitely helps others that find the thread later when they're having similar issues.
Link to comment
Share on other sites

Glad to hear that all is well. To answer your question:

winWait("Setup Complete")
winActivate("Setup Complete")
winWaitActive("Setup Complete")

<{POST_SNAPBACK}>

Wouldn't I be just giving it basically the same command twice??? Yeah, winWait() would wait for the window, but so would winActivate(), and winWaitActive() would do the same thing as all 3.... right???

<{POST_SNAPBACK}>

No -- the difference is subtle but the functionality varies greatly.

In the case of a window appearing and stealing the focus at that time, both blocks of code are functionally identical. However, take the case where a window appears on-screen but (because Windows is Windows) it doesn't get focus.

At this point a WinWaitActive() would stop in its tracks until a user manually focuses the window in question. My code above will automatically ensure the the window receives focus in either case.

Basically I would recommend to anyone waiting for a new window to appear and take focus to use the code above as it guarantees that the window will have focus. It can also be wrapped into a function to keep code looking clean:

func winWaitReady($title, $text = "")
    winWait($title, $text)
    winActivate($title, $text)
    winWaitActive($title, $text)
endFunc

One other thing I would recommend if using this is to decrease the WinWaitDelay via Opt().

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