karmayogi Posted November 13, 2008 Share Posted November 13, 2008 (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 expandcollapse popupLocal $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 November 13, 2008 by karmayogi I came, I saw and I copied. Link to comment Share on other sites More sharing options...
Valik Posted November 13, 2008 Share Posted November 13, 2008 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) Link to comment Share on other sites More sharing options...
karmayogi Posted November 13, 2008 Author Share Posted November 13, 2008 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. Link to comment Share on other sites More sharing options...
Valik Posted November 14, 2008 Share Posted November 14, 2008 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(). Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now