Jump to content

$GUI_EVENT_CLOSE delay in loop


Recommended Posts

When the form is open, I do an instant service check, but when I close the gui, it closes late.

#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
$Form1 = GUICreate("Form1", 512, 223, 192, 124)
$InstantWinupControl = GUICtrlCreateLabel("", 104, 104, 332, 17)
GUISetState(@SW_SHOW)
While 1
    ;windows update status control
    If StringInStr(CheckService(), "Running") Then
        GUICtrlSetData($InstantWinupControl, "Win update service opened")
    Else
        GUICtrlSetData($InstantWinupControl, "Win update service is turned off")
    EndIf
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit

    EndSwitch
WEnd

Func CheckService()
    $ServiceName = "wuauserv"
    Local $ServicesUp = ObjGet("winmgmts:\\" & @ComputerName & "\root\cimv2")
    Local $ServicesUpList = $ServicesUp.ExecQuery("SELECT * FROM Win32_Service")
    If IsObj($ServicesUpList) Then
        For $ServicesUp In $ServicesUpList
            If $ServicesUp.Name = $ServiceName Then
                If $ServicesUp.State = "Running" Then
                    Return "Running"
                EndIf
            EndIf
        Next
    EndIf
EndFunc   ;==>CheckService

 

Link to comment
Share on other sites

How long does that Query take to return?

Most likely you are waiting for control to be returned to AutoIt from the query so that it can process the event loop.

Can you put a where clause in the query to make it return quicker?

Btw, you should put a Sleep(10) in your While loop, just to give the CPU a break.  It won’t effect anything that you could ever notice.

Code hard, but don’t hard code...

Link to comment
Share on other sites

9 minutes ago, argumentum said:

nope. GUIGetMsg() takes care of that.

In this case, maybe not.

Since the OP is complaining about a delay in closing the GUI, we can assume that it is > 1 sec. 

Which implies that the Query is running for seconds at a time, and it runs all the time in the loop.

So we have something like this looping

CheckService() - takes >1 sec

GUIGetMsg() - idles for >=10 ms

CheckService() - takes >1 sec

GUIGetMsg() - idles for >=10 ms

CheckService() - takes >1 sec

GUIGetMsg() - idles for >=10 ms

which means that that CPU may be pegged regardless depending on the query profile.

This also means that my suggestion is equally useless.

If the OP needs the query to run continously, then so be it.  If he doesn't he's better off not running the query constantly but using a timer to execute every second or so,

 

Code hard, but don’t hard code...

Link to comment
Share on other sites

@Deye

it doesn't work for me lag continues

#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>

$Form1 = GUICreate("Form1", 512, 223, 192, 124)
$InstantWinupControl = GUICtrlCreateLabel("", 104, 104, 332, 17)

GUISetState(@SW_SHOW)
While 1
    AdlibRegister("CheckService", 5000)
    If StringInStr(CheckService(), "Running") Then
        GUICtrlSetData($InstantWinupControl, "Win update service opened")
    Else
        GUICtrlSetData($InstantWinupControl, "Win update service is turned off")
    EndIf
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            AdlibUnRegister("CheckService")
            Exit

    EndSwitch
WEnd

Func CheckService()
    $ServiceName = "wuauserv"
    Local $ServicesUp = ObjGet("winmgmts:\\" & @ComputerName & "\root\cimv2")
    Local $ServicesUpList = $ServicesUp.ExecQuery("SELECT * FROM Win32_Service")
    If IsObj($ServicesUpList) Then
        For $ServicesUp In $ServicesUpList
            If $ServicesUp.Name = $ServiceName Then
                If $ServicesUp.State = "Running" Then
                    Return "Running"
                EndIf
            EndIf
        Next
    EndIf
EndFunc   ;==>CheckService

 

Link to comment
Share on other sites

Try it like so (using a shorter function ..)

#include <GUIConstantsEx.au3>
#include <constants.au3>

$Form1 = GUICreate("Form1", 512, 223, 192, 124)
$InstantWinupControl = GUICtrlCreateLabel("", 104, 104, 332, 17)
GUISetState(@SW_SHOW)

CheckService()
AdlibRegister("CheckService", 5000)

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd

Func CheckService()
    $pid = Run(@ComSpec & ' /c sc query wuauserv | findstr STATE', '', @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)
    Local $data
    Do
        $data &= StdoutRead($pid)
    Until @error
    If StringInStr($data, 'RUNNING') Then
        GUICtrlSetData($InstantWinupControl, "Win update service opened")
    Else
        GUICtrlSetData($InstantWinupControl, "Win update service is turned off")
    EndIf
EndFunc   ;==>CheckService

 

Link to comment
Share on other sites

It worked fine when equating the Label to $nMsg

#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
$Form1 = GUICreate("Form1", 512, 223, 192, 124)
$InstantWinupControl = GUICtrlCreateLabel("", 104, 104, 332, 17)
GUISetState(@SW_SHOW)
While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $nMsg = $InstantWinupControl
            If StringInStr(CheckService(), "Running") Then
                GUICtrlSetData($InstantWinupControl, "Win update service opened")
            Else
                GUICtrlSetData($InstantWinupControl, "Win update service is turned off")
            EndIf
        Case $GUI_EVENT_CLOSE
            Exit

    EndSwitch
WEnd

Func CheckService()
    $ServiceName = "wuauserv"
    Local $ServicesUp = ObjGet("winmgmts:\\" & @ComputerName & "\root\cimv2")
    Local $ServicesUpList = $ServicesUp.ExecQuery("SELECT * FROM Win32_Service")
    If IsObj($ServicesUpList) Then
        For $ServicesUp In $ServicesUpList
            If $ServicesUp.Name = $ServiceName Then
                If $ServicesUp.State = "Running" Then
                    Return "Running"
                EndIf
            EndIf
        Next
    EndIf
EndFunc   ;==>CheckService

 

 

Link to comment
Share on other sites

@Deye The nice thing about using WMI, it is very simple to replace @ComputerName with a remote system hostname.  Sure, you can do it with SC as well, but extra parsing is involved.

@youtuber If you want to continue using WMI, you can optimize the WMI query to return faster.

$ServicesUp.ExecQuery("SELECT Name, State FROM Win32_Service Where Name = '" & $ServiceName & "'")

I also agree with Deye's approach of moving the GUICtrlSetData functions into the CheckService function.

Edited by spudw2k
Link to comment
Share on other sites

I might do it this way.

Spoiler
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
$Form1 = GUICreate("Form1", 512, 223, 192, 124)
$InstantWinupControl = GUICtrlCreateLabel("", 104, 104, 332, 17)
GUISetState(@SW_SHOW)
CheckService()
While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            AdlibUnRegister("CheckService")
            Exit
    EndSwitch
WEnd


Func CheckService()
    Local $sServiceName = "wuauserv"
    Local $sResultMsg = WMIGetServiceState($sServiceName)
    If @error Then
        $sResultMsg = "CheckService WMI Query Failed"
    Else
        $sResultMsg = "Win update service is " & $sResultMsg
    EndIf
    GUICtrlSetData($InstantWinupControl, $sResultMsg)
    AdlibRegister("CheckService", 5000)
EndFunc   ;==>CheckService

Func WMIGetServiceState($sServiceName, $sHostname = @ComputerName)
    Local $oServicesUp = ObjGet("winmgmts:\\" & $sHostname & "\root\cimv2")
    Local $oServicesUpList = $oServicesUp.ExecQuery("SELECT Name, State FROM Win32_Service WHERE Name = '" & $sServiceName & "'")
    If IsObj($oServicesUpList) And $oServicesUpList.Count > 0 Then
        For $oServicesUp In $oServicesUpList
            Return $oServicesUp.State
        Next
    Else
        Return SetError(1, 0, "")
    EndIf
EndFunc   ;==>WMIGetServiceState

 

 

Edited by spudw2k
minor correct in example, additional (proper) error checking
Link to comment
Share on other sites

Maybe this streamlined version ?

#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>

GUICreate("Form1", 512, 223, 192, 124)
Local $InstantWinupControl = GUICtrlCreateLabel("", 104, 104, 332, 17)
GUISetState()
While 1
  Switch GUIGetMsg()
    Case $GUI_EVENT_CLOSE
      Exit
  EndSwitch
  If CheckService() Then
    GUICtrlSetData($InstantWinupControl, "Win update service opened")
  Else
    GUICtrlSetData($InstantWinupControl, "Win update service is turned off")
  EndIf
WEnd

Func CheckService()
  Local Static $ServicesUp = ObjGet("winmgmts:\\.\root\cimv2")
  Local $ServicesUpList = $ServicesUp.ExecQuery("SELECT * FROM Win32_Service WHERE name = 'wuauserv' and state = 'Running'")
  Return $ServicesUpList.count
EndFunc   ;==>CheckService

 

Edited by Nine
better coded version
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...