Jump to content

Run / RunWait and Exit Codes


Recommended Posts

wraithdu, it doesn't matter what the application should not use. The fact is that some application can use exit code STILL_ACTIVE.

If you ignore it as possibility user of your function could really be stuck in an infinite loop waiting for 0.

It should really be:

;...
    ElseIf $iExit[2] = 259 Then
        ; process STILL_ACTIVE
        If _WinApi_WaitForSingleObject($hProc, 0) = $WAIT_OBJECT_0 Then Return SetExtended($iExit[2], 0)
        Return 1
    Else
;...

... as suggested.

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

wraithdu,

Actually - I misremembered the bit about Redirecting I/O.  I thought it was the process handle that had to be kept open, but its actually the pipe handles.  I found the MSDN example I was thinking of - Creating a Child Process with Redirected Input and Output.  D'oh :mad2:  .  Oddly the example closes the Input handle but leaves out closing the read handle (a member commented about it at the bottom, however).

Anyway, I'm still unclear as to why you would rely on STILL_ACTIVE - it doesn't matter that MSDN only talks about it on reading the Exit Code of a Process/Thread - there's no guidelines about return values in C, C++ or any other language as to specifically not returning the value 259, which would obviously be absurd.  Its an entirely valid exit code.  Even MSDN's topics on WinMain and main() don't mention the value.

All I'm saying is that one call to WaitForSingleObject can fix that code.  If it returns non-zero, the process is still alive.

*edit - looks like trancexx beat me to the punch!

Edited by Ascend4nt
Link to comment
Share on other sites

wraithdu,

It seems I was too quick to give a gracious comment on your functions without looking into the technical aspect.

I disagree with the design of your functions. I am surprised that you state that they both come from the same project. One function returns an array while the other accepts just a value. This creates a possible error condition which can be avoided if the functions were designed to work together. It's bad programming. The amount of error checking and knowledge to handle them is not as simple as compared to my functions. I must press on the knowledge as you try to handle STILL_ACTIVE without making a clear mention in your summary with the code. My decision was to avoid STILL_ACTIVE by informing users that testing for exitcode only after the process is closed is required! You do not set this explicit requirement and thus the exitcode returned can be 259 and the user of your function may be none the wiser. Using STILL_ACTIVE in your functions means that user code needs extra code to handle this condition.

I guess your functions have not had extensive testing and use to have seen these issues that need correction. An example would also be nice to see how to handle the functions, with the needed error handling, so people of these function have "full knowledge and understanding".

Note: A return value in the header does not reflect the value that your last function may return. I accept this as a simple error yet another error condition.

Hopefully your functions can be redesigned and trusted to avoid the error conditions that can be created.

 

Link to comment
Share on other sites

Yes, they both came from the same project. It seems my purpose was just different from yours. The first function returns an array because both the process handle and PID are important pieces of data that I needed. The exists function only requires the handle however, simple as that. Nowhere did I say you could just pass one return as a parameter to the other.

The new handling of the STILL_ACTIVE exit code (courtesy of Ascend4nt and trancexx) is adequate I think. It sounds as though your function was meant to only retrieve the exit code, while mine foremost was meant to test if the process still existed, and return the exit code when it has ended.

Care to elaborate on what you don't understand from the last function return values? I believe the header covers all three: return, extended, and error.

Link to comment
Share on other sites

I now consider the return may be correct but they are confusing to use. The concern of handling all 3 return types is not good design. For example, success can return a value of 0 or 1 while failure can be 0. This reminds me of my initial decision to avoid STILL_ACTIVE as handling it creates UDFs which are a nightmare to use. Ease of use is a core design to the functions I created. AutoIt already has ProcessExists and other process functions which can handle the issue well so I still believe today that my decision was a good one.

The only need was and still is at present, is to simply get the exitcode. I solved this issue several years ago and the technical view that it may fail one in a trillion times is not enough of a concern when I compare it to using code which is not easy to use. Thus, I consider that you post your UDFs in the Examples Forum with the preparation needed so people can try them. Developing them in this thread is of no interest to me as the topic has already achieved an answer IMO.

I have wasted enough time over this and I am not going to waste more by solving what has already been solved. If I need to return to this thread then I may lose my rational thinking and also my patience. I am moving on with other concerns that do need my attention.

Link to comment
Share on other sites

My functions were not intended for the Examples forum, just for the OP's issue. They were ripped from another project, so use them (or don't) as you see fit. I'll note that my other reason for the Exists function is that calling the built-in ProcessExists() in a tight loop (as was my need) causes high CPU usage. My function does not have this overhead.

As far as I'm concerned you can keep your debate and comparison to yourself. It was not my intent to compare to anyone else or prove anyone wrong. In particular your needs / functions / rational thinking are not my concern. If you find something useful, use it. If you have something constructive to say, do so. But your last two posts were not constructive in my opinion, and I'll agree with your appraisal that they were indeed a waste of your time.

Link to comment
Share on other sites

  • 3 weeks later...

Firstly thanks for the replies

I finally got time to look at this problem so i started with funkeys example

My two cents:

#include <WinAPI.au3>

Global Const $PROCESS_ALL_ACCESS = 0x1F0FFF

Global $iPID = Run("test.exe")
ConsoleWrite("PID: " & $iPID & @LF)
Global $hProcess = _WinAPI_OpenProcess($PROCESS_ALL_ACCESS, 1, $iPID)
ConsoleWrite("Process handle: " & $hProcess & @LF)
ProcessWaitClose($iPID)
Global $aRet = DllCall("kernel32.dll", "bool", "GetExitCodeProcess", "HANDLE", $hProcess, "dword*", -1)
ConsoleWrite("Exit code: " & $aRet[2] & @LF)

BTW: The only way how Run() could provide the exit code is through a callback function I think. But this is really not necessary.

 

as it seemed the easiest to implement at this time before i tried the more difficult ones.

I managed to get it running with notepad as an example, but as soon as i add it into the script it throws an error

 

: ERROR: $PROCESS_ALL_ACCESS previously declared as a 'Const'.

Global Const $PROCESS_ALL_ACCESS = 0x1F0FFF
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^

 

Now i assumed somewhere in one of the includes this existed so i tested every one im using for the thread $PROCESS_ALL_ACCESS even WinApi doesnt have it?

So am I using the wrong version or do i need beta or something?

This are the includes i checked for it

 

#include <ButtonConstants.au3>

#include <GUIConstantsEx.au3>
#include <ProgressConstants.au3>
#include <Array.au3>
#include <Misc.au3>
#include <WindowsConstants.au3>
#include <Constants.au3>
#include "RecFileListToArray.au3"
#include <WinAPI.au3>

 

Or have i missed something obvious?

Edited by Chimaera
Link to comment
Share on other sites

That constant is declared in ProcessConstants.au3, which is included by Constants.au3. The error simply means it was already declared (as a Const) and you tried to declare it again, which you can't. Just comment it out of your script.

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