Sign in to follow this  
Followers 0
karmayogi

RunAs with ProcessWaitClose

4 posts in this topic

#1 ·  Posted (edited)

Guys,

I am not sure if anyone else has encountered this problem, but I have been wrestling with this for a while now.

I am using build 3.2.12.1 of AutoIt. I am creating a script, converting it to an exe and launching the exe, so that SciTe is out of the picture.

Here are my requirements

1) I need to spawn off a process using a separate set of credentials. I do that using RunAs()

2) I also need a handle to the out and error stream of my child process, hence my decision to use RunAs() instead of RunAsWait()

3) Next I invoke ProcessWaitClose() with the PID returned by the RunAs call.

4) When the ProcessWaitClose() method returns, the documentation mentions that the @extended variable should have the exit code of my child process. That is incorrect. I do not get any exit code and it consistently comes back with the value -858993460, no matter what I run.

By the way my child process itself is running, does what it needs to do etc, just that in case I send in exit codes from my child, it never makes it to my autoit script.

Am I looking at this incorrectly ? Is there another way to achieve both, i.e get exit codes as well as handle error and out streams. My child processes are always console based and I don't have to worry about windows.

Here's a snippet of my code that aims to achieve this

Local $pid = RunAs($sUser, $sDomain, $sPassword, 0, $sCmd, $sTempDir,@SW_HIDE,8)

If $pid = 0 Then
    $errCode = @error
    if $errCode <> 0 Then
        $errMsg = "An attempt to login as user " & $sUserName & " on domain " & $sDomain & " failed. Please check the credentials and ensure that you can login manually to the host where this error occurred using this credential."
    EndIf
Else
    $errCode = $pid;$pid
    debug("Ret = " & $errCode)
EndIf
Local $line=""

While 1
    $line = StdoutRead($pid)
    If @error Then ExitLoop
  if $line <> "" Then
    info($line)
Else
;nothing
EndIf
Wend
While 1
    $line = StderrRead($pid)
    If @error Then ExitLoop
    if $line <> "" Then
    info($line)
Else
;nothing
EndIf

Wend

; Wait for the process to close.
Local $retVal = ProcessWaitClose($pid,$processTimeout)
$errCode = @extended
debug(@error)
If ($retVal = 1) Then
    
Else
    $errCode = "-1";
EndIf


debug("Return code is :"& $errCode);

Appreciate any pointers

Yogi

Edited by karmayogi

I came, I saw and I copied.

Share this post


Link to post
Share on other sites



ProcessWaitClose() sets that value if the PID is no longer valid (needs documented). The way your script is written that is always going to be the case. It will stay in the first While loop until the process is closed because StdoutRead() won't set @error until the process is closed. The simplest solution is to do this (pseudo-code):

Local $pid = RunAs()
ProcessWaitClose($pid)
Local $nExitCode = @extended
Local $sStdOut = StdoutRead($pid)
Local $sStdErr = StderrRead($pid)

Share this post


Link to post
Share on other sites

Valik,

You are da man.

That worked. I was suspicious that something like that might be happening, but my earlier attempts did not produce good results because of the following reason.

In some cases when my child process exits with an error, it is so fast that between the time the RunAs is called and the ProcessWaitClose is called, the PID disappears, so I still catch the out and err streams, but my exit code is gone.

Any ideas on how I can solve that problem ?

Thanks a bunch

Yogi.

ProcessWaitClose() sets that value if the PID is no longer valid (needs documented). The way your script is written that is always going to be the case. It will stay in the first While loop until the process is closed because StdoutRead() won't set @error until the process is closed. The simplest solution is to do this (pseudo-code):

Local $pid = RunAs()
ProcessWaitClose($pid)
Local $nExitCode = @extended
Local $sStdOut = StdoutRead($pid)
Local $sStdErr = StderrRead($pid)

I came, I saw and I copied.

Share this post


Link to post
Share on other sites

Call ProcessWaitClose() *immediately* after calling RunAs(). If that doesn't work then you'll need to call the Windows API functions OpenProcess(), GetExitCodeProcess() and CloseHandle() to script the sequence yourself. Some of those are available as UDF's, others will require DllCall().

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