Jump to content

Need help with making a scripted install work


Recommended Posts

Hi everyone,

I've done real basic stuff with AutoIT but never anything advanced until now.

Our phone vendor has a unified messaging program/snap-in for Outlook and provided no method to do an unattended install, so scripting with AutoIT is our only option.

I have a GUI that prompts the user for their extension number and voicemail password. The script passes these values to the install at the appropriate times.

The problem I'm running into is during error handling. There are a few different scenarios that occur after the install is done: either it's successful or it sends one of three errors.

Each of these error windows have the same title, but different text within them.

I thought I could pull something off like what I have below, but my script seems to hang and never do anything. Is there a better/easier way to do this? Note, the plethora of commands under each if/elseif statement is just to get the installation to complete, then pop up an error message telling the user what's wrong.

If WinWait("Cannot Verify Service Settings","The E-mail Gateway is not set to") Then
    ;Unified Messaging Not enabled for this mailbox
        ControlClick("Cannot Verify Service Settings","","Button2")
        WinWait("Unified Messaging Service","")
        If Not WinActive("Unified Messaging Service","") Then WinActivate("Unified Messaging Service","")
        ControlClick("Unified Messaging Service","","Button2")
        WinWait("Installation Complete - Step 11 of 11","")
        If Not WinActive("Installation Complete - Step 11 of 11","") Then WinActivate("Installation Complete - Step 11 of 11","")
        WinWaitActive("Installation Complete - Step 11 of 11","")
        Send("!f")
        errorWindow("Installation Error","Your mailbox is not currently enabled for unified messaging." & @CRLF & "Please contact the help desk for support." & @CRLF & "Unified Messagins is NOT installed.")

    ElseIf WinWait("Cannot Verify Service Settings","The mailbox that you have entered") Then
    ;Mailbox does not exist
        ControlClick("Cannot Verify Service Settings","","Button2")
        WinWait("Unified Messaging Service","")
        If Not WinActive("Unified Messaging Service","") Then WinActivate("Unified Messaging Service","")
        ControlClick("Unified Messaging Service","","Button2")
        WinWait("Installation Complete - Step 11 of 11","")
        If Not WinActive("Installation Complete - Step 11 of 11","") Then WinActivate("Installation Complete - Step 11 of 11","")
        WinWaitActive("Installation Complete - Step 11 of 11","")
        Send("!f")
        errorWindow("Installation Error","The mailbox you have entered does not exist." & @CRLF & "Please contact the help desk for support." & @CRLF & "Unified Messagins is NOT installed.")

    ElseIf WinWait("Cannot Verify Service Settings","mailbox password you entered") Then
    ;Incorrect voicemail password
        ControlClick("Cannot Verify Service Settings","","Button2")
        WinWait("Unified Messaging Service","")
        If Not WinActive("Unified Messaging Service","") Then WinActivate("Unified Messaging Service","")
        ControlClick("Unified Messaging Service","","Button2")
        WinWait("Installation Complete - Step 11 of 11","")
        If Not WinActive("Installation Complete - Step 11 of 11","") Then WinActivate("Installation Complete - Step 11 of 11","")
        WinWaitActive("Installation Complete - Step 11 of 11","")
        Send("!f")
        errorWindow("Installation Error","The mailbox password you have entered is incorrect." & @CRLF & "Please contact the help desk for support." & @CRLF & "Unified Messagins is NOT installed.")

    ElseIf WinWait("Installation Complete - Step 11 of 11","") Then
    ;Install Succeeded
        If Not WinActive("Installation Complete - Step 11 of 11","") Then WinActivate("Installation Complete - Step 11 of 11","")
        WinWaitActive("Installation Complete - Step 11 of 11","")
        Send("!f")
    EndIf
Link to comment
Share on other sites

A WinWait is going to pause the script until the errors are there. Have you tried doing WinExists?

For example:

; Run The Code that starts the install process
;Sleep for a given amount of time when you think the error will be there
If WinExists("Cannot Verify Service Settings", "The E-mail Gateway is not set to") Then
   ;Do your controlclicks here
EndIf

[sub]Quantum mechanics: The dreams stuff is made of[/sub]

Link to comment
Share on other sites

I tried WinExists as well, but I had issues with that.

Immediately before that chunk of code is the brunt of the install where the install is copying files, registering stuff, and doing whatever installs do, so depending on the PC it's running on it could take anywhere between 5-45 seconds. Wouldn't WinExists check for the window's presence at that instant and not wait for it?

I figured putting a WinWait for any possible window would allow the script to hang out and wait for something to pop up before it continued on.

Link to comment
Share on other sites

Wouldn't WinExists check for the window's presence at that instant and not wait for it?

I figured putting a WinWait for any possible window would allow the script to hang out and wait for something to pop up before it continued on.

You are correct, the only problem I see with that is if that error window never pops up, your script will just set there and wait for the window. Your only other option would be to set a timeout for WinWait(), but the problem with that is now you are stuck waiting a period of seconds, as you said that could be 5-45 seconds.

[sub]Quantum mechanics: The dreams stuff is made of[/sub]

Link to comment
Share on other sites

...but my script seems to hang and never do anything...

Welcome to the forum.

It might help you to know exactly which line of AutoIt code your script is stopping on.

Try adding this Opt line near the top of your script...

AutoItSetOption("TrayIconDebug", 1)  ;0-off
Hope this helps.

[size="1"][font="Arial"].[u].[/u][/font][/size]

Link to comment
Share on other sites

Yeah, I caught that and fixed it when I was updating my script.

I'm interacting a lot with the windows during the install (using Send to send text to input boxes, ControlClick and ControlCommand to click buttons, check checkboxes, etc.) I don't suppose there's any easy method to "hiding" this from the user beyond throwing an always-on-top window across their screen during the install, is there?

Link to comment
Share on other sites

First let me mention that I made a few errors in the code that I provided. I'm surprised that it worked, but at the kind prompting of another forum member via a PM to me, I've done what I should have done before posting that code.

You see, I was not sure how/where the AdLib function returns so I made what I thought was a loop - it turns out that it will only "loop" once (probably should not even call that a loop) since I did not include a timeout in the WinWait line after the Until.

It turns out that the AdLib function will interrupt the WinWait and return to that same WinWait line quite nicely as you can see when you mouse over the AutoIt icon while running this code:

AutoItSetOption("TrayIconDebug", 1)  ;0-off
AdlibEnable("Errors", 10000)

WinWait("Installation Complete - Step 11 of 11", "")

Func Errors()
    MsgBox(0, "", "")
EndFunc   ;==>ErrorsoÝ÷ ØajÆÞzv¥¢x-g¬w#ozëvØZ´K·îËb¢{(";¬·¬m)äx-)à²ØkºízËbax,)"ÈhºWaj÷².ØZ½éuæZ.¶íà¨Úè)brKÛajÕ¢f¢¶«¨µIâ~'1ë,j§'«¾'ªê-ªê-ªê-)Þ{-y§h~Zr)àÖµêò¢êÈñ%±âüIÝ!÷(uãî¶Ø§+pêÞ!ØÂ¥v­ºÊâ[iÉ"Ú0j+bè­¬"Ú0¶­(!¶z-mëaz·¢èZvØ^¶*'¡ûajÖ¶*'rëyËmçâ®ËmgºÚ"µÍYX[XJ   ][ÝÑÜÉ][ÝÊBÚ[ØZ]
    ][ÝÒ[Ý[][ÛÛÛ]HHÝLHÙLI][ÝË ][ÝÉ][ÝÊBÒ[Ý[ÝXØÙYYYÚ[]]][ÝÒ[Ý[][ÛÛÛ]HHÝLHÙLI][ÝË ][ÝÉ][ÝÊBÚ[ØZ]]J   ][ÝÒ[Ý[][ÛÛÛ]HHÝLHÙLI][ÝË ][ÝÉ][ÝÊBÙ[
    ][ÝÉÌÌÎÙ][ÝÊB[ÈÜÊ
BYÚ[^ÝÊ  ][ÝÐØ[ÝYHÙXÙHÙ][ÜÉ][ÝË   ][ÝÕHK[XZ[Ø]]Ø^HÈÝÙ]É][ÝÊH[Õ[YYYYÜØYÚ[ÈÝ[XYÜÈXZ[ÞÐ×ÑÜÊ
BÜÚ[ÝÊ  ][ÝÒ[Ý[][ÛÜ][ÝË  ][ÝÖ[ÝXZ[ÞÈÝÝ[H[XYÜ[YYYYÜØYÚ[Ë][ÝÈ    [ÈÔ   [È ][ÝÔXÙHÛÛXÝH[ÚÈÜÝÜ][ÝÈ [ÈÔ   [È ][ÝÕ[YYYYÜØYÚ[ÈÈÕ[Ý[Y][ÝÊB[ÙRYÚ[^ÝÊ  ][ÝÐØ[ÝYHÙXÙHÙ][ÜÉ][ÝË   ][ÝÕHXZ[Þ][ÝH]H[Y   ][ÝÊH[ÓXZ[ÞÙÈÝ^ÝÐ×ÑÜÊ
BÜÚ[ÝÊ  ][ÝÒ[Ý[][ÛÜ][ÝË  ][ÝÕHXZ[Þ[ÝH]H[YÙÈÝ^Ý][ÝÈ [ÈÔ   [È ][ÝÔXÙHÛÛXÝH[ÚÈÜÝÜ][ÝÈ [ÈÔ   [È ][ÝÕ[YYYYÜØYÚ[ÈÈÕ[Ý[Y][ÝÊB[ÙRYÚ[^ÝÊ  ][ÝÐØ[ÝYHÙXÙHÙ][ÜÉ][ÝË   ][ÝÛXZ[ÞÜÝÛÜ[ÝH[Y   ][ÝÊH[Ò[ÛÜXÝÚXÙ[XZ[ÜÝÛÜÐ×ÑÜÊ
BÜÚ[ÝÊ  ][ÝÒ[Ý[][ÛÜ][ÝË  ][ÝÕHXZ[ÞÜÝÛÜ[ÝH]H[[ÛÜXÝ][ÝÈ    [ÈÔ   [È ][ÝÔXÙHÛÛXÝH[ÚÈÜÝÜ][ÝÈ [ÈÔ   [È ][ÝÕ[YYYYÜØYÚ[ÈÈÕ[Ý[Y][ÝÊB[Y[[ÈÏOIÝÑÜÂ[ÈÐ×ÑÜÊ
BÛÛÛÛXÚÊ  ][ÝÐØ[ÝYHÙXÙHÙ][ÜÉ][ÝË   ][ÝÉ][ÝË    ][ÝÐ]Û][ÝÊBÚ[ØZ]
    ][ÝÕ[YYYYÜØYÚ[ÈÙXÙI][ÝË   ][ÝÉ][ÝÊBÛÛÛÛXÚÊ  ][ÝÕ[YYYYÜØYÚ[ÈÙXÙI][ÝË   ][ÝÉ][ÝË    ][ÝÐ]Û][ÝÊB[[ÈÏOIÝÐÐ×ÑÜ

...I don't suppose there's any easy method to "hiding" this from the user beyond throwing an always-on-top window across their screen during the install, is there?

A full screen SplashTextOn might do what you want or maybe SplashImageOn. I'm not positive and cannot test right now - but you might have to stay away from Send if you are working with a window that is not on top. Perhaps ControlSend will work instead.

Maybe other have used other methods of hiding such actions.

[size="1"][font="Arial"].[u].[/u][/font][/size]

Link to comment
Share on other sites

I was working on a auto-installer for winamp (boredom), which you might find something useful in(yeah, I know the methods I use are overkill, but I was bored):

#include <WinAPI.au3>
#Include <GuiTreeView.au3>

Opt("WinTitleMatchMode", 4)

Dim $InstallFile = @ScriptDir & "\winamp552_full_emusic-7plus_en-us.exe"
Dim $InstallDir = @ProgramFilesDir & "\Winamp"

Dim $InstallComponents[5][2]
$InstallComponents[0][0] = "Winamp Agent" ; Title
$InstallComponents[0][1] = False ; Install: True or False
$InstallComponents[1][0] = "Multimedia Engine" ; Title
$InstallComponents[1][1] = True ; Install: True or False
$InstallComponents[2][0] = "Winamp Library" ; Title
$InstallComponents[2][1] = True ; Install: True or False
$InstallComponents[3][0] = "User Interface Extensions" ; Title
$InstallComponents[3][1] = True ; Install: True or False
$InstallComponents[4][0] = "Visualization" ; Title
$InstallComponents[4][1] = True ; Install: True or False

Dim $InstallOptions[7]
$InstallOptions[0] = "Winamp" ; Start-Menu folder title
$InstallOptions[1] = False ; Create Start-Menu entry
$InstallOptions[2] = True ; Create Quick-Launch icon
$InstallOptions[3] = False ; Create Desktop icon
$InstallOptions[4] = False ; Install Winamp Remote
$InstallOptions[5] = False ; Install Winamp Toolbar
$InstallOptions[6] = False ; Get 50 Free MP3 Downloads from eMusic

Dim $LaunchAfterInstall = True ; Launch winamp after install is complete
Dim $MinimizeInstallWindow = True ; Hide the installer window..
Dim $Debug = False ; Won't press install at the end if True

; Don't edit the code below(unless you know what you're doing.)
; Don't edit the code below(unless you know what you're doing.)
; Don't edit the code below(unless you know what you're doing.)



If Not FileExists($InstallFile) Then
    $InstallFile = FileOpenDialog("Select the winamp installer file", @DesktopDir, ".Exe(*.exe)", 3, "winamp552_full_emusic-7plus_en-us.exe")
    If @error Then _Exit("Error, an installer file was not selected!")
EndIf

Dim $iPID = Run($InstallFile)
Dim $aWindowHandle

$aWindowHandle = _ProcessWaitWinEx($iPID, "", 4500, "#32770")
If @Error Then _Exit("Error, installer automation failed: Installer window not found")

If Not _ControlWaitVisible($aWindowHandle[$aWindowHandle[0]], "", "Button1", 4500) Then _Exit("Error, there was an error automating the window: A control could not be handled")
ControlClick($aWindowHandle[$aWindowHandle[0]], "", "Button1")

$aWindowHandle = _ProcessWaitWinEx($iPID, "", 4500, "#32770")
If @Error Then _Exit("Error, installer automation failed: Installer window not found")

If $MinimizeInstallWindow Then
    WinSetState($aWindowHandle[$aWindowHandle[0]], "", @SW_MINIMIZE)
EndIf
If Not _ControlWaitVisible($aWindowHandle[$aWindowHandle[0]], "", "Button2", 4500) Then _Exit("Error, there was an error automating the window: A control could not be handled")
ControlClick($aWindowHandle[$aWindowHandle[0]], "", "Button2")

If Not _ControlWaitVisible($aWindowHandle[$aWindowHandle[0]], "", "Button2", 4500) Then _Exit("Error, there was an error automating the window: A control could not be handled")
ControlClick($aWindowHandle[$aWindowHandle[0]], "", "Button2")

If Not _ControlWaitVisible($aWindowHandle[$aWindowHandle[0]], "", "Edit1", 4500) Then _Exit("Error, there was an error automating the window: A control could not be handled")
ControlSetText($aWindowHandle[$aWindowHandle[0]], "", "Edit1", $InstallDir)
ControlClick($aWindowHandle[$aWindowHandle[0]], "", "Button2")

If Not _ControlWaitVisible($aWindowHandle[$aWindowHandle[0]], "", "SysTreeView321", 4500) Then _Exit("Error, there was an error automating the window: A control could not be handled")

_SelectFeatures(ControlGetHandle($aWindowHandle[$aWindowHandle[0]], "", "SysTreeView321"))

ControlClick($aWindowHandle[$aWindowHandle[0]], "", "Button2")

If Not _ControlWaitVisible($aWindowHandle[$aWindowHandle[0]], "", "Edit1", 4500) Then _Exit("Error, there was an error automating the window: A control could not be handled")
ControlSetText($aWindowHandle[$aWindowHandle[0]], "", "Edit1", $InstallOptions[0])

For $i = 1 To UBound($InstallOptions)-1
    If $InstallOptions[$i] Then
        If $i < 4 Then
            ControlCommand($aWindowHandle[$aWindowHandle[0]], "", "Button" & $i+3, "Check", "")
        Else
            ControlCommand($aWindowHandle[$aWindowHandle[0]], "", "Button" & $i, "Check", "")
        EndIf
    Else
        If $i < 4 Then
            ControlCommand($aWindowHandle[$aWindowHandle[0]], "", "Button" & $i+3, "UnCheck", "")
        Else
            ControlCommand($aWindowHandle[$aWindowHandle[0]], "", "Button" & $i, "UnCheck", "")
        EndIf
    EndIf
    If $i = 3 Then 
        ControlClick($aWindowHandle[$aWindowHandle[0]], "", "Button2")
        If Not _ControlWaitVisible($aWindowHandle[$aWindowHandle[0]], "", "Button4", 4500) Then _Exit("Error, there was an error automating the window: A control could not be handled")
    EndIf
Next

If Not $Debug Then
    ControlClick($aWindowHandle[$aWindowHandle[0]], "", "Button2")
Else
    MsgBox(0, "Woop", "Nearly there now. ;P I Will exit when you click ok. :P")
    Exit
EndIf

If Not _ControlWaitVisible($aWindowHandle[$aWindowHandle[0]], "", "Button4", 60*2*1000) Then _Exit("Error, there was an error automating the window: A control could not be handled")
If $LaunchAfterInstall Then
    ControlCommand($aWindowHandle[$aWindowHandle[0]], "", "Button4", "Check", "")
Else
    ControlCommand($aWindowHandle[$aWindowHandle[0]], "", "Button4", "UnCheck", "")
EndIf
ControlClick($aWindowHandle[$aWindowHandle[0]], "", "Button2")

Func _SelectFeatures($ivControlhWnd)
    
    Local $ivItemhWnd
    
    For $i = 0 To UBound($InstallComponents)-1
        $ivItemhWnd = _GUICtrlTreeView_FindItem($ivControlhWnd, $InstallComponents[$i][0])
        If Not $ivItemhWnd Then _Exit("Error, a feature could not be found(installer version incompabillities?)")
        If $InstallComponents[$i][1] Then
            _GUICtrlTreeView_SetChecked ($ivControlhWnd, $ivItemhWnd, True)
        Else
            _GUICtrlTreeView_SetChecked ($ivControlhWnd, $ivItemhWnd, False)
        EndIf
    Next
    
EndFunc

Func _ControlWaitVisible($ivWindowhWnd, $svText, $ivControlID, $ivTimeout = 0)
    
    If Not WinExists($ivWindowhWnd, $svText) Then
        SetError(1) ; window doesn't exist
        Return 0
    EndIf
    
    Local $ivTimer = TimerInit()
    
    Do
        Sleep(250)
    Until ControlCommand($ivWindowhWnd, "", $ivControlID, "IsVisible", "") Or ($ivTimeout > 0 And TimerDiff($ivTimer) > $ivTimeout)
    
    If $ivTimeout > 0 And TimerDiff($ivTimer) > $ivTimeout Then
        SetError(2) ; Timeout
        Return 0
    EndIf
    
    SetError(0)
    Return 1
    
EndFunc

Func _ProcessWaitWinEx($ivPID, $svText = "", $ivTimeout = 0, $svClass = "")
    
    If Not ProcessExists($ivPid) Then
        SetError(3) ; Process doesn't exist
        Return 0
    EndIf
    
    Local $ivTimer = TimerInit()
    Local $avWindows
    
    Do
        Sleep(250)
        $avWindows = _ProcessGetWinEx($ivPid, $svClass)
    Until (IsArray($avWindows) And $avWindows[0] > 0) Or (TimerDiff($ivTimer) > $ivTimeout And $ivTimeout > 0)
    
    If Not IsArray($avWindows) Or $avWindows[0] < 1 Then
        SetError(1) ; No windows found
        Return 0
    ElseIf TimerDiff($ivTimer) > $ivTimeout And $ivTimeout > 0 Then
        SetError(2) ; Timed out
        Return 0
    EndIf
    
    SetError(0)
    Return $avWindows
    
EndFunc

Func _ProcessGetWinEx($ivPid, $svClass = "")
    
    $ivPid = ProcessExists($ivPid)
    If Not $ivPid Then Return(SetError(1, 0, 0))
    
    Local $avwArray = WinList()
    Local $avRet[1] = [0]
    
    For $i = 1 To $avwArray[0][0]
        If WinGetProcess($avwArray[$i][1]) = $ivPid Then
            If $svClass = "" Or _WinAPI_GetClassName($avwArray[$i][1]) = $svClass Then
                $avRet[0] += 1
                ReDim $avRet[$avRet[0]+1]
                $avRet[$avRet[0]] = $avwArray[$i][1]
            EndIf
        EndIf
    Next
    
    Return $avRet
    
EndFunc

Func _Exit($svMessage)
    MsgBox(0, "Error", $svMessage)
    Exit
EndFunc

Func OnAutoItExit()
    If IsDeclared("iPID") Then
        ProcessClose($iPID) 
    EndIf
EndFunc

To test it you need the winamp installer: http://www.soft32.com/Download/Free/Winamp/4-7565-1.html Link should be safe...

Edited by FreeFry
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...