tk1 Posted November 24, 2014 Posted November 24, 2014 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
Luigi Posted November 24, 2014 Posted November 24, 2014 (edited) 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 expandcollapse popup#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 November 24, 2014 by Detefon Visit my repository
ZacUSNYR Posted November 24, 2014 Posted November 24, 2014 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.
tk1 Posted November 24, 2014 Author Posted November 24, 2014 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. expandcollapse popup;~ . ;~ . ;~ . 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
kylomas Posted November 25, 2014 Posted November 25, 2014 tk1, Not enough info. We need to see how you are managing GuiGetMsg and gui creation. Can you post the entire script? kylomas Forum Rules Procedure for posting code "I like pigs. Dogs look up to us. Cats look down on us. Pigs treat us as equals." - Sir Winston Churchill
tk1 Posted November 25, 2014 Author Posted November 25, 2014 kylomas, I am not using GUIGetMsg, maybe that's the piece I'm missing (?). This is my script (scrubbed of any identifiable information): expandcollapse popup#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
kylomas Posted November 26, 2014 Posted November 26, 2014 (edited) No, event mode should be OK... edit: don't have time to find all the crap needed to run this...maybe later... Edited November 26, 2014 by kylomas Forum Rules Procedure for posting code "I like pigs. Dogs look up to us. Cats look down on us. Pigs treat us as equals." - Sir Winston Churchill
MikahS Posted November 26, 2014 Posted November 26, 2014 (edited) 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. Edited November 26, 2014 by MikahS Snips & Scripts My Snips: graphCPUTemp ~ getENVvarsMy 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
BrewManNH Posted November 26, 2014 Posted November 26, 2014 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 GudeHow 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
tk1 Posted December 1, 2014 Author Posted December 1, 2014 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
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now