Jump to content

Wait for one of two buttons to be pressed


tk1
 Share

Recommended Posts

Hello,

I am writing a script to perform a software install if that software is not already installed.  If it already is installed, I'm displaying the version in the GUI window with an Install button and a Close button.  How do I get the script to wait at that point for me to either click the Install or Close button?

I tried using a While 1 loop with just sleep 100, and it worked in so far as the script stopped at the right point with the GUI showing correctly, however clicking either button does not invoke their associated function (they are defined and those functions do work otherwise).

How do I get the script to stop at that point, wait for one of the two buttons to be clicked, and then continue based on which button was clicked?

Thank you,

tk1

Link to comment
Share on other sites

Hello @tk1, here a little example, it not use while loop to get when a button is pressed, it is start by event.

A long time ago, I use only a normal loop, with while...wend.

Today I use only GuiCtrlCreateOnEvent... Is more clear.
The main loop is not too fat...

Br, Detefon

#AutoIt3Wrapper_AU3Check_Parameters= -q -d -w 1 -w 2 -w 3 -w- 4 -w 5 -w 6 -w- 7
#Tidy_Parameters=/sf

#include-once
#include <Array.au3>
#include <Misc.au3>
#include <GUIConstantsEx.au3>

OnAutoItExitRegister("_EXIT_BEFORE")

Opt('GUIOnEventMode', 1)
Opt('GUIEventOptions', 1)
Opt('MustDeclareVars', 1)
Opt('WinWaitDelay', 25)

Global $aGuiSize[2] = [800, 600]
Global $sGuiTitle = "GuiTitle"
Global $hGui
Global $hButton

$hGui = GUICreate($sGuiTitle, $aGuiSize[0], $aGuiSize[1])
GUISetOnEvent($GUI_EVENT_CLOSE, '_EXIT')
$hButton = GUICtrlCreateButton('button', 10, 10, 80, 20)
GUICtrlSetOnEvent($hButton, "button")

GUISetState(@SW_SHOW, $hGui)

While Sleep(10)
WEnd

Func button()
    ConsoleWrite("button")
EndFunc

Func _EXIT()
    Exit
EndFunc   ;==>_EXIT

Func _EXIT_BEFORE($sInput = 0)
    If IsDeclared("sInput") Then ConsoleWrite("_exit[ " & $sInput & " ]" & @LF)
    GUIDelete($hGui)
EndFunc   ;==>_EXIT_BEFORE
Edited by Detefon

Visit my repository

Link to comment
Share on other sites

You should have an idle loop for a GUI, it sounds like you're not returning from another loop and getting back to the idle loop so the GUI is not responding?

Use the idle loop and associate a global variable, just check the global variable?

When the button is pressed, update the idle loop.  You can start with the button disabled and it enable it when it's available for a press?

Post your script and we can check it out.  All you're going to get is ideas without seeing what you're doing.

Link to comment
Share on other sites

You're right, ZacUSNYR.

 

Here is a snippet of the code.

fuCheckInstall  is a function that reads the registry and checks to see if the utility is installed.

fuInstallerChoose  is a function that just hides some labels and shows the Install and Close buttons on the GUI.

fuInstallUtility  is the function that performs the install/upgrade.

The vertical ellipses are where other code (including the GUI creation) exists that is unrelated to this question, so I stripped it out for brevity.

;~  .
;~  .
;~  .

While 1
    Sleep(100)
WEnd

Func btnNextClick()
;~  .
;~  .
;~  .

;~  If Utility is already installed, user chooses next step; otherwise deposit the installer file.
    If fuCheckInstall() Then ;Utility is already installed.
        GUICtrlSetData($lblInstructions, "Utility " & $sProgVersion & " is already installed." & @CRLF & @CRLF & _
                "For a clean install, click Install." & @CRLF & "To exit without doing anything, click Close.")
        fuInstallerChoose() ;Shows GUI with Install and Close buttons.
    Else ;Utility is not installed.
        GUICtrlSetData($lblStatus, "Extracting the installer file.")
;~      The FileInstalls are inside the If Then so only one of them gets extracted at run time.
        If @OSArch <> "X86" Then
            FileInstall("C:\Files\Utility-x64.msi", $sInstFile, 1)
        Else
            FileInstall("C:\Files\Utility-x86.msi", $sInstFile, 1)
        EndIf
    EndIf

;~  The following should only be called if the "Install" button is clicked.
    fuInstallUtility()

EndFunc   ;==>btnNextClick
;~  .
;~  .
;~  .

Func fuInstallerChoose() ;Prepare GUI to for user choice.
    GUICtrlSetState($lblPlsWait, $GUI_HIDE)
    GUICtrlSetState($lblStatus, $GUI_HIDE)
    GUICtrlSetState($lblInstructions, $GUI_SHOW)
    GUICtrlSetState($btnInstall, $GUI_SHOW)
    GUICtrlSetState($btnClose, $GUI_SHOW + $GUI_FOCUS)
EndFunc   ;==>fuInstallerChoose

Func CLOSEClicked()
    Exit
EndFunc   ;==>CLOSEClicked

Func btnCloseClick()
    Exit
EndFunc   ;==>btnCloseClick
Link to comment
Share on other sites

kylomas, I am not using GUIGetMsg, maybe that's the piece I'm missing (?).

This is my script (scrubbed of any identifiable information):

#RequireAdmin
#cs ----------------------------------------------------------------------------

    #Region ;**** Directives created by AutoIt3Wrapper_GUI ****
    #AutoIt3Wrapper_Icon=..\Files\Logo.ico
    #AutoIt3Wrapper_Res_Description=Utility Installer
    #AutoIt3Wrapper_Res_Fileversion=0.9.0.0
    #AutoIt3Wrapper_Res_Language=1033
    #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

#ce ----------------------------------------------------------------------------

#pragma compile(Icon, ..\Files\Logo.ico)
#pragma compile(FileDescription, Utility Installer)
#pragma compile(FileVersion, 0.9.0.0)
#pragma compile(ProductName, Utility)
#pragma compile(ProductVersion, 0.9.0.0)

#include <Services.au3>
#include <SecurityEx.au3>
#include <MsgBoxConstants.au3>
#include <GUIConstantsEx.au3>
#include <ButtonConstants.au3>
#include <ProgressConstants.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <Uninstall.au3>

;Set variables
Global $sBase_x64 = "HKLM64\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\" ;avoids redirection to x86
Global $sBase_x32 = "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\"
Global $sUtility64 = "Utility-x64.msi" ;Referenced here and in FileInstall() below (1x)
Global $sUtility32 = "Utility-x86.msi" ;Referenced here and in FileInstall() below (1x)
Global $sBitness = $sBase_x32
Global $fStatus = False
Global $sInstFile
Global $sDeploymentServer = "Utilitydeployment.domain.com"
Global $sDeploymentPort = "12345"
Global $sInstallerVersion = FileGetVersion(@ScriptFullPath)
Global $sInstLblTxt = "When you are ready to install Utility, please press Next."
Global $sProgVersion

Opt("GUIOnEventMode", 1) ;Enable OnEvent functions notifications.
Opt("TrayIconHide", 1) ;Hides tray icon, although it may still be visible for 750ms until it gets hidden.

FileInstall("C:\Files\Logo.gif", @TempDir & "\Logo.gif", 1)

;Now, create the form and populate it.
$frmMain = GUICreate("Utility Installer  " & $sInstallerVersion, 630, 350, -1, -1)
GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEClicked")
GUISetBkColor(0xffffff)

$lblTitle = GUICtrlCreateLabel("Utility Installer", 5, 15, 620, 72, $SS_CENTER)
GUICtrlSetFont(-1, 19, 800, 0, "Arial")

$picNGlogo = GUICtrlCreatePic(@TempDir & "\Logo.gif", 45, 120, 90, 90)

$lblInstructions = GUICtrlCreateLabel($sInstLblTxt, 205, 130, 400, 150)
GUICtrlSetFont(-1, 12, 500, 0, "Arial")
GUICtrlSetState(-1, $GUI_SHOW)

$lblPlsWait = GUICtrlCreateLabel("Please wait for the installation to finish.", 205, 110, 400, 20)
GUICtrlSetFont(-1, 12, 500, 0, "Arial")
GUICtrlSetState(-1, $GUI_HIDE)

$lblStatus = GUICtrlCreateLabel("", 205, 160, 300, 20) ;300 width = 43 characters
GUICtrlSetFont(-1, 10, 400, 0, "Arial")
GUICtrlSetState(-1, $GUI_HIDE)

$btnNext = GUICtrlCreateButton("Next", 500, 290, 73, 33)
GUICtrlSetFont(-1, 11, 400, 0, "Arial")
GUICtrlSetState(-1, $GUI_FOCUS)
GUICtrlSetOnEvent(-1, "btnNextClick")

$btnClose = GUICtrlCreateButton("Close", 500, 290, 73, 33)
GUICtrlSetFont(-1, 11, 400, 0, "Arial")
GUICtrlSetState(-1, $GUI_HIDE)
GUICtrlSetOnEvent(-1, "btnCloseClick")

$btnInstall = GUICtrlCreateButton("Install", 400, 290, 73, 33)
GUICtrlSetFont(-1, 11, 400, 0, "Arial")
GUICtrlSetState(-1, $GUI_HIDE)
GUICtrlSetOnEvent(-1, "btnInstallClick")

;Now show the form.
GUISetState(@SW_SHOW)

;Infinite loop.
While 1
    Sleep(100)
WEnd

Func btnNextClick()
    GUICtrlSetState($lblInstructions, $GUI_HIDE)
    GUICtrlSetState($lblPlsWait, $GUI_SHOW)
    GUICtrlSetState($btnNext, $GUI_HIDE)
;~  Set bitness of OS and the external file necessary for Utility install.
    If @OSArch <> "X86" Then
        GUICtrlSetData($lblStatus, "64")
        $sBitness = $sBase_x64
        $sInstFile = @TempDir & "\" & $sUtility64
    Else
        GUICtrlSetData($lblStatus, "32")
        $sInstFile = @TempDir & "\" & $sUtility32
    EndIf

    GUICtrlSetState($lblStatus, $GUI_SHOW)
    Sleep(750) ;Make status visible.

;~  Check if the correct install file will be downloaded.
    If StringInStr($sInstFile, @OSArch, 0, -1) Then ;@OSArch should be either "X64" or "X86".
        GUICtrlSetData($lblStatus, "Install file correctly matches OS bitness.")
    Else
        $sInstLblTxt = "ERROR:" & @CRLF & "OS and install file bitness MIS-MATCH!" & @CRLF & @CRLF & "Please report this error."
        fuInstallFailed()
        Return ;Exit the function so the installer can be closed on a failed install.
    EndIf

    Sleep(750) ;Make status visible.

;~  If Utility is already installed, user chooses next step; otherwise deposit the installer file.
    If fuCheckInstall() Then ;Utility is already installed.
        GUICtrlSetData($lblInstructions, "Utility " & $sProgVersion & " is already installed." & @CRLF & @CRLF & _
                "For a clean install, click Install." & @CRLF & "To exit without doing anything, click Close.")
        fuInstallerChoose() ;Shows GUI with Install and Close buttons.

;~      While 1
;~          Sleep(100)
;~      WEnd
    Else ;Utility is not installed.
        GUICtrlSetData($lblStatus, "Extracting the installer file.")
;~      The FileInstalls are inside the If Then so only one of them gets extracted at run time.
        If @OSArch <> "X86" Then
            FileInstall("C:\Utility\Utility-x64.msi", $sInstFile, 1)
        Else
            FileInstall("C:\Utility\Utility-x86.msi", $sInstFile, 1)
        EndIf
    EndIf

    Sleep(500) ;Make status visible.

;~  Install Utility.
    fuInstallUtility()

;~  Verify Utility is installed, if so, then deposit config files.
    If fuCheckInstall() Then
        GUICtrlSetData($lblStatus, "Utility is now installed." & @CRLF & "The config files will now be copied.")
        fuCopyConfigFolders()
        GUICtrlSetData($lblStatus, "Getting ready to close the installer.")
        GUICtrlSetData($lblInstructions, "Utility is now installed." & @CRLF & @CRLF & "Please press the Close button.")
        fuCloseInstallerPrep()
    Else
        $sInstLblTxt = "Utility installation FAILED."
        fuInstallFailed()
    EndIf
EndFunc   ;==>btnNextClick

Func fuCheckInstall()
    Local $iEval = 1 ;Counter for installed software.

    While 1
        Local $sDisplay = "" ;For DisplayName of the software (from the registry).
        Local $sCurrent = RegEnumKey($sBitness, $iEval) ;Gets the software name from the registry.
        If @error Then ExitLoop
        Local $sKey = $sBitness & $sCurrent ;The location and name of the key in the registry.
        $sDisplay = RegRead($sKey, "DisplayName") ;Reads the (display) name of the software.

        If StringInStr($sDisplay, "Utility") Then
            $sProgVersion = RegRead($sKey, "DisplayVersion") ;Version of the software.
            $fStatus = True
            ExitLoop
        EndIf
        $iEval += 1
    WEnd

    Return $fStatus
EndFunc   ;==>fuCheckInstall

Func fuInstallUtility()
;~  Command line is:  msiexec.exe /i <the .msi file> DEPLOYMENT_SERVER="Utilitydeployment.domain.com : 12345" AGREETOLICENSE=Yes /quiet
    $sInstFile = "msiexec.exe /i " & $sInstFile & " INSTALLDIR=""C:\Program Files\Utility"" " & _
            "DEPLOYMENT_SERVER=""Utilitydeployment.domain.com : 12345"" AGREETOLICENSE=Yes /quiet"
    GUICtrlSetData($lblStatus, "Utility is now being installed.")
    RunWait($sInstFile)

EndFunc   ;==>fuInstallUtility

Func fuCopyConfigFolders()
;~  Stop the Utility service.
    GUICtrlSetData($lblStatus, "Stopping the Utility service.")
    _Service_Stop("UtilityService")
    Sleep(500) ;Make status visible.

;~  Make sure subdirectories exist.
    GUICtrlSetData($lblStatus, "Creating the folders for the config files.")
    DirCreate("C:\Program Files\Utility\Config\local\")
    DirCreate("C:\Program Files\Utility\Config\metadata\")
    Sleep(500) ;Make status visible.

;~  Copy config files.
    GUICtrlSetData($lblStatus, "Copying the config files into the folders.")
    FileInstall("C:\Utility\2copy\local\config1.ini", "C:\Program Files\Utility\Config\local\", 1)
    FileInstall("C:\Utility\2copy\local\config2.ini", "C:\Program Files\Utility\Config\local\", 1)
    FileInstall("C:\Utility\2copy\metadata\config.dat", "C:\Program Files\Utility\Config\metadata\", 1)
    Sleep(500) ;Make status visible.

;~  Restart Utility service.
    GUICtrlSetData($lblStatus, "Restarting the Utility service.")
    _Service_Start("UtilityService")
    GUICtrlSetData($lblStatus, "The Utility service has been restarted.")
    Sleep(500) ;Make status visible.

EndFunc   ;==>fuCopyConfigFolders

Func fuCloseInstallerPrep() ;Prepare GUI to close.
    GUICtrlSetState($lblPlsWait, $GUI_HIDE)
    GUICtrlSetState($lblStatus, $GUI_HIDE)
    GUICtrlSetState($lblInstructions, $GUI_SHOW)
    GUICtrlSetState($btnClose, $GUI_SHOW + $GUI_FOCUS)
EndFunc   ;==>fuCloseInstallerPrep

Func fuInstallerChoose() ;Prepare GUI to for user choice.
    GUICtrlSetState($lblPlsWait, $GUI_HIDE)
    GUICtrlSetState($lblStatus, $GUI_HIDE)
    GUICtrlSetState($lblInstructions, $GUI_SHOW)
    GUICtrlSetState($btnInstall, $GUI_SHOW)
    GUICtrlSetState($btnClose, $GUI_SHOW + $GUI_FOCUS)
EndFunc   ;==>fuInstallerChoose

Func fuInstallFailed()
;~  fuPostInstallCleanup()
    GUICtrlSetState($lblPlsWait, $GUI_HIDE)
    GUICtrlSetState($lblStatus, $GUI_HIDE)
    GUICtrlSetData($lblInstructions, $sInstLblTxt)
    GUICtrlSetState($lblInstructions, $GUI_SHOW)
    GUICtrlSetState($btnClose, $GUI_SHOW + $GUI_FOCUS)
EndFunc   ;==>fuInstallFailed

Func CLOSEClicked()
    Exit
EndFunc   ;==>CLOSEClicked

Func btnCloseClick()
    Exit
EndFunc   ;==>btnCloseClick

Func btnInstallClick()
    $lblStatus = "Existing Utility is being uninstalled."
    GUICtrlSetState($lblPlsWait, $GUI_SHOW)
    GUICtrlSetState($lblStatus, $GUI_SHOW)
    GUICtrlSetState($lblInstructions, $GUI_HIDE)
    GUICtrlSetState($btnInstall, $GUI_HIDE)
    GUICtrlSetState($btnClose, $GUI_HIDE)
    fuUninstall("Utility")
    $lblStatus = "Existing Utility has been uninstalled."
    Return

EndFunc   ;==>btnInstallClick

tk1

Link to comment
Share on other sites

I think all your troubles will be alieviated if you used GUIGetMsg(). Comment out the OnEvent calls, and change the Opt() to mode 0. Then replace the while loop you have with this:

;; Instead of using OnEvent mode, this could be a lot easier
Opt("GUIOnEventMode", 0)

Local $msg

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $GUI_EVENT_CLOSE
            CLOSEClicked()
        Case $btnNext
            btnNextClick()
        Case $btnClose
            btnCloseClick()
        Case $btnInstall
            btnInstallClick()
    EndSwitch
WEnd

Give it a try and let us know if using GUIGetMsg() works for you and fixes the problem you are having. :)

EDIT: My apologies, Kylomas and BrewMan are correct. :D

Edited by MikahS

Snips & Scripts


My Snips: graphCPUTemp ~ getENVvars
My Scripts: Short-Order Encrypter - message and file encryption V1.6.1 ~ AuPad - Notepad written entirely in AutoIt V1.9.4

Feel free to use any of my code for your own use.                                                                                                                                                           Forum FAQ

 

Link to comment
Share on other sites

The 2 methods would work the same in this script, messageloop mode as you wrote it won't give him anything more than what he already has.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

The 2 methods would work the same in this script, messageloop mode as you wrote it won't give him anything more than what he already has.

 

So, is there no way to do this, or am I still confused?

tk1

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