Jump to content

Terminate program based on 2 conditions not working


Recommended Posts

I' working on this code:

;coded by UEZ build 2014-02-08, idea taken from http://codepen.io/Fahrenheit/pen/Kbyxu
;AutoIt v3.3.9.21 or higher needed!
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <Constants.au3>
#include <WindowsConstants.au3>

_GDIPlus_Startup()
Global Const $STM_SETIMAGE = 0x0172; $IMAGE_BITMAP = 0
;Global $iW = 1920, $iH = 1080
Global $iW = 920, $iH = 680
;Global $Color_white = 0x3C3C3C3C
Global Const $hGUI = GUICreate("One moment...", $iW, $iH, -1, -1, $WS_POPUP, $WS_EX_TOPMOST)
Global Const $iPic = GUICtrlCreatePic("", 650, 350, $iW, $iH)
;Global Const $iPic = GUICtrlCreatePic("", 250, 50, $iW, $iH)
GUICtrlSetState(-1, $GUI_DISABLE)
GUISetBkColor($Color_white)
GUISetState()

Global $hHBmp_BG, $hB, $iPerc = 0, $iSleep = 60, $s = 0, $t, $m = 0
GUIRegisterMsg($WM_TIMER, "PlayAnim")
DllCall("user32.dll", "int", "SetTimer", "hwnd", $hGUI, "int", 0, "int", $iSleep, "int", 0)

Global $DOS, $Message = '' ;; added "= ''" for show only.
Global $sProcess = "calc.exe", $iDummy = GUICtrlCreateDummy(), $iAmountProcesses = 1

Do
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE, $iDummy
            GUIRegisterMsg($WM_TIMER, "")
            _WinAPI_DeleteObject($hHBmp_BG)
            _GDIPlus_Shutdown()
            GUIDelete()
            Exit
    EndSwitch
    $aPL = ProcessList($sProcess)
    $DOS = Run(@ComSpec & ' /c tasklist /S server1 /U server1\admin /P password /FI "USERNAME eq '  & @UserName & '" /FI "IMAGENAME eq calc*"', "", @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)
    ProcessWaitClose($DOS)
    $Message = StdoutRead($DOS)
    Local $Proq = StringInStr($Message, "calc.exe")
    If IsArray($aPL) Then
        If $aPL[0][0] > $iAmountProcesses - 1 Then
           if $Proq > 1 Then
             GUICtrlSendToDummy($iDummy)
           EndIf
        Else
            ;$iPerc = $aPL[0][0] / $iAmountProcesses * 100
        EndIf
    EndIf
Until False

The code is longer but I haven't changed it beyond here so I only am listing this part.  It's the nested if statement that I think is giving a problem:  if $Proq > 1 then.  

The program brings up an animation. The animation has to keep running until both calc.exe processes are running: one on the local computer and one on the remote computer server1. Behavior now is that the animation never stops.

Link to comment
Share on other sites

  • Moderators

You need to add some error checking to help you determine how far you're getting before it fails, rather than guessing. Something like this should get you started (typo warning, on my phone):

If IsArray($aPL) Then
        If $aPL[0][0] > $iAmountProcesses - 1 Then
           if $Proq > 1 Then
             GUICtrlSendToDummy($iDummy)
           Else
             MsgBox($MB_OK, "Error", "$aProq = " & $aProq)
           EndIf
        Else
            MsgBox($MB_OK, "Error", "$aPL[0][0] = " & $aPL[0][0] & ", not $iAmountProcesses - 1")
        EndIf
    Else
        MsgBox($MB_OK, "Error", "$aPL does not exist!")
    EndIf

 

 

"Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball

How to get your question answered on this forum!

Link to comment
Share on other sites

This is the output I get in the Messagebox when the local calc process is not running:   

$aPL[0][0] = 0, not $iAmountProcesses - 1

When the local calc and remote calc are running I get the 2nd message:  $Proq = 159
 

The tasklist thing is pretty clumsy, needs about 5 seconds to return output. Could this be a timing problem?

Link to comment
Share on other sites

  • Moderators

Try it with WMI and see if it is any faster:

Const $wbemFlagReturnImmediately = "&h10"
Const $wbemFlagForwardOnly = "&h20"

Local $sPC = "server1"
Local $oWMI = ObjGet("winmgmts:\\" & $sPC & "\root\cimv2")
    If IsObj($oWMI) Then
        $oItems = $oWMI.ExecQuery("SELECT * FROM Win32_Process", "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly)
            If $oItems.Count > 0 Then
                For $sProcess In $oItems
                    If StringInStr($sProcess.Name, "calc") Then ConsoleWrite($sProcess.Name & @CRLF)
                Next
            EndIf
    EndIf

If you determine it is just an issue with TaskList, you may need to build some sleep time into the script.

"Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball

How to get your question answered on this forum!

Link to comment
Share on other sites

Sorry Wbem won't work because needs to run under the locally logged on user in a Citrix environment. There are security restrictions in place here.  How can I let the program wait for tasklist eg 5 seconds. And what about the order of this code:

$DOS = Run(@ComSpec & ' /c tasklist /S server1 /U server1\admin /P password /FI "USERNAME eq '  & @UserName & '" /FI "IMAGENAME eq calc*"', "", @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)
    ProcessWaitClose($DOS)
    $Message = StdoutRead($DOS)
    Local $Proq = StringInStr($Message, "calc.exe")

It's new, wasn't originally there. Neither was 

 if $Proq > 1 Then

So I modded the original version which only checked for a local version of calc.exe and worked fine. Didn't really know where to paste the new code. I have the feeling that the order or location of the code is not correct.

Link to comment
Share on other sites

After some thought I don't think the slow tasklist is causing the problems. ProcessWaitClose($DOS) says to wait till finished. And indeed the program did wait about 6 or 7 seconds until the debug messagebox appeared. Must be a wrong order or wrong logic :>

Link to comment
Share on other sites

@JLogan3o13: I tested your WMI code anyhow just to see what was causing the delays. Turns out you were right, tasklist is messing things up. If I replace the tasklist code with the WMI code all works well as admin. Unfortunately I can't use WMI because the remote call gets executed under the user's security context and thus is restricted since these are users, not admins.

I found out that instead of doing a remote tasklist call I can do 2 local checks for 2 different local processes. That was pretty easy and is now working.

Thanks for the guidance!

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