Sign in to follow this  
Followers 0
anixon

Process Exists

15 posts in this topic

#1 ·  Posted (edited)

When closing Outlook 2003 in a Windows Vista environment it can take approximately 5+ seconds on my Desktop for the 'outlook.exe' process to stop being reported as running in the Windows Task Manager. My guess is that Outlook performs some houskeeping tasks as part of its closing process which gives the impression when using 'ProcessExists' that it is still running even though it is in the process of closing down.

I have used the following test code that reports that the process exists during the 5+ seconds after it has been closed using the standard [X] Windows Close command.

The problem is that on occasions it would be possible to get a false positive indication that Outlook was running in circumstances where it has actually in the process of closing either invoked by the user or some other process.

Is there a better methodology other than embedding 'ProcessExists' into a do until statement that loops for the 5+ seconds that continually checks that outlook is running so as not to obtain the false positive.

_CheckOutlook()

Func _CheckOutlook()
Local $i
Do
  If Not ProcessExists("outlook.exe") Then
   MsgBox(0, "", "Does not exist",1)
  Else
   MsgBox(0, "", "Exist",1)
  EndIf
  $i += 1
Until $i = 10
EndFunc   ;==>_StopOutlook

Comments on this issue would be appreciated.. Ant.. :)

Edited by anixon

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

You could attempt to implement something like:

_WinAPI_WaitForMultipleObjects()

_WinAPI_WaitForSingleObject()

Edit:

Or ProcessWaitClose()

Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

You could attempt to implement something like:

_WinAPI_WaitForMultipleObjects()

_WinAPI_WaitForSingleObject()

Edit:

Or ProcessWaitClose()

Thanks for the prompt response unfortunately I am not familar with _WinAPI_...... so if I can put you to the trouble it would be helpful if you could give me an example of how it might be used in my situation. I'll check out your other suggestion 'processwaitclose' Ant..

_Outlook()

Func _Outlook()
  If ProcessExists("outlook.exe") Then ProcessWaitClose("Outlook.exe", 20)
  If Not ProcessExists("outlook.exe") Then
   MsgBox(0, "", "Does not exist",1)
  Else
   MsgBox(0, "", "Exist",1)
  EndIf
EndFunc   ;==>_StopOutlook
Edited by anixon

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

ProcessWaitClose more than likely uses the API's suggested.

It has a time out feature as well, so that's all you'd need more than likely, it has plenty of return/@error/@extended information to help you.

Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites

When closing Outlook 2003 in a Windows Vista environment it can take approximately 5+ seconds on my Desktop for the 'outlook.exe' process to stop being reported as running in the Windows Task Manager. My guess is that Outlook performs some houskeeping tasks as part of its closing process which gives the impression when using 'ProcessExists' that it is still running even though it is in the process of closing down.

I have used the following test code that reports that the process exists during the 5+ seconds after it has been closed using the standard [X] Windows Close command.

The problem is that on occasions it would be possible to get a false positive indication that Outlook was running in circumstances where it has actually in the process of closing either invoked by the user or some other process.

Is there a better methodology other than embedding 'ProcessExists' into a do until statement that loops for the 5+ seconds that continually checks that outlook is running so as not to obtain the false positive.

_CheckOutlook()

Func _CheckOutlook()
Local $i
Do
  If Not ProcessExists("outlook.exe") Then
   MsgBox(0, "", "Does not exist",1)
  Else
   MsgBox(0, "", "Exist",1)
  EndIf
  $i += 1
Until $i = 10
EndFunc   ;==>_StopOutlook

Comments on this issue would be appreciated.. Ant.. :)

If I understand you correctly, your saying that you expect that ProcessExists() should return 0 as soon as you click the X to close it, but as you say the process still exists while Outlook cleans up, if this is true then ProcessExist() is working absolutely fine.

Quite a few applications do this, for example Opera web browser also does this. If you close it, it cleans up before the process terminates sometimes taking 15 seconds or more.

Share this post


Link to post
Share on other sites

If I understand you correctly, your saying that you expect that ProcessExists() should return 0 as soon as you click the X to close it, but as you say the process still exists while Outlook cleans up, if this is true then ProcessExist() is working absolutely fine.

Quite a few applications do this, for example Opera web browser also does this. If you close it, it cleans up before the process terminates sometimes taking 15 seconds or more.

Share this post


Link to post
Share on other sites

Processexists works perfectly so the issue was really how best to detect that [X] had been clicked and the application was in the process of being closed. This code appears to overrcome the issue.

;//Check that Outlook is Running
Func _CheckOutlookStatus()
 ;//Make sure Outlook is not in processing a [X] 'Close'
 If ProcessExists("outlook.exe") Then ProcessWaitClose("Outlook.exe", 10)
 ;//Restart Outlook if Not Running
 If Not ProcessExists("outlook.exe") Then
  ;//Start Outlook and Re-create the Object
  _StartOutlook()
 EndIf
EndFunc

Share this post


Link to post
Share on other sites

If ProcessExists("outlook.exe") and NOT WinExists("Whatever the outlook gui window is called") then

;Its in the process of closing

Endif

The only issue with looking at the gui window is called is that it might not always have the same handle it could be 'Inbox - Microsoft Outlook' or 'Junk E-mail - Microsoft Outlook' unless of course WinExists checks all or just part of the name? Ant..

Share this post


Link to post
Share on other sites

The only issue with looking at the gui window is called is that it might not always have the same handle it could be 'Inbox - Microsoft Outlook' or 'Junk E-mail - Microsoft Outlook' unless of course WinExists checks all or just part of the name? Ant..

Depends on the Opt("WinTitleMatchMode") you have set.

Share this post


Link to post
Share on other sites

#12 ·  Posted (edited)

Depends on the Opt("WinTitleMatchMode") you have set.

Better to use the window class I'd think:

Something like this maybe:

_WaitForOutlookToClose(15)
If Not @error Then
    ConsoleWrite("Outlook.exe is closed and process does not exist." & @CRLF)
ElseIf @error = 1
    ConsoleWrite("Timed out waiting for Outlook.exe and Window to close." & @CRLF)
Else
    ConsoleWrite("Timed out waiting for Outlook.exe to close." & @CRLF)
EndIf

Func _WaitForOutlookToClose($i_timeout = -1) ; timeout in secs; default is no timeout

    $i_timeout = Int($i_timeout)

    Local $i_timer = TimerInit()
    Local $f_timeout = False, $i_retval
    If $i_timeout > 0 Then $f_timeout = True

    While 1
        $i_retval = _IsOutlookAlive()
        If ($i_retval = 0) Then ExitLoop
        If ($i_retval And @extended = 0) Then
            While _IsOutlookAlive()
                If $f_timeout Then
                    If (TimerDiff($i_timer) / 1000) > $i_timeout Then
                        Return SetError(2, 0, 0)
                    EndIf
                EndIf
                Sleep(250)
            WEnd
            Return 1
        EndIf
        If $f_timeout Then
            If (TimerDiff($i_timer) / 1000) > $i_timeout Then
                Return SetError(1, 0, 0)
            EndIf
        EndIf
        Sleep(250)
    WEnd

    Return 1
EndFunc

Func _IsOutlookAlive()

    Local $i_pid = ProcessExists("Outlook.exe")

    ; Outlook doesn't exist; extended shows it's closed completely
    If Not $i_pid Then Return SetError(1, 0, 0)

    Local $a_winlist = WinList("[REGEXPCLASS:rctrl_renwnd.*?]")

    ; Outlook exists, but is closing/cleaning/starting up
    ;  or class is wrong
    If Not IsArray($a_winlist) Then Return SetError(2, 0, 1)

    For $i = 1 To $a_winlist[0][0]
        If WinGetProcess($a_winlist[$i][1]) = $i_pid Then
            ; Outlook is alive and not shuttind down
            ; Extended will show this
            Return SetError(0, 1, 1)
        EndIf
    Next

    ; Outlook exists, but is closing/cleaning/starting up
    ;  or class is wrong

    Return SetError(2, 0, 1)
EndFunc
Edited by SmOke_N
fixed code / last change

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites

Better to use the window class I'd think:

Something like this maybe:

_WaitForOutlookToClose(15)
If Not @error Then
    ConsoleWrite("Outlook.exe is closed and process does not exist." & @CRLF)
Else
    ConsoleWrite("Timed out waiting for Outlook.exe to close." & @CRLF)
EndIf

Func _WaitForOutlookToClose($i_timeout = -1) ; timeout in secs; default is no timeout

    $i_timeout = Int($i_timeout)

    Local $i_timer = TimerInit()
    Local $f_timeout = False
    If $i_timeout > 0 Then $f_timeout = True

    While 1
        _IsOutlookAlive()
        If Not @extended Then ExitLoop
        If $f_timeout Then
            If (TimerDiff($i_timer) / 1000) > $i_timeout Then
                Return SetError(1, 0, 0)
            EndIf
        EndIf
        Sleep(250)
    WEnd

    Return 1
EndFunc

Func _IsOutlookAlive()

    Local $i_pid = ProcessExists("Outlook.exe")

    ; Outlook doesn't exist; extended shows it's closed completely
    If Not $i_pid Then Return SetError(1, 0, 0)

    Local $a_winlist = WinList("[REGEXPCLASS:rctrl_renwnd.*?]")

    ; Outlook exists, but is closing/cleaning/starting up
    ;  or class is wrong
    If Not IsArray($a_winlist) Then Return SetError(2, 0, 1)

    For $i = 1 To $a_winlist[0][0]
        If WinGetProcess($a_winlist[$i][1]) = $i_pid Then
            ; Outlook is alive and not shutting down
            ; Extended will show this
            Return SetError(0, 1, 1)
        EndIf
    Next

    ; Outlook exists, but is closing/cleaning/starting up
    ;  or class is wrong

    Return SetError(2, 0, 1)
EndFunc

Thanks guys you have been a great help not only to me but my guess many other subscribers as well. The suggest solutions including the SmOke_N code example will make a great addition to my how to reference library thanks again. I guess all that I have left to say is 'so much to learn so little time left' Ant.. Posted Image

Share this post


Link to post
Share on other sites

#14 ·  Posted (edited)

I had to change the code I provided... It's Sunday, and I must admit, it looks sloppy to me still.

But it does seem to work.

Edit:

Made last change to it... have fun.

If anything, might give you an idea to better manage it.

Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites

I had to change the code I provided... It's Sunday, and I must admit, it looks sloppy to me still.

But it does seem to work.

Edit:

Made last change to it... have fun.

If anything, might give you an idea to better manage it.

Thanks for making the effort which was very much appreciated Ant..

Share this post


Link to post
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
Sign in to follow this  
Followers 0