Sign in to follow this  
Followers 0
flyingboz

StdOutRead() with PSEXEC

10 posts in this topic

Has anyone had success using Run() with the STDOUT_CHILD , STDERR_CHILD flags to process psexec data? I can read the first line only with scripts that process other commands flawlessly.


Reading the help file before you post... Not only will it make you look smarter, it will make you smarter.

Share this post


Link to post
Share on other sites



Has anyone had success using Run() with the STDOUT_CHILD , STDERR_CHILD flags to process psexec data? I can read the first line only with scripts that process other commands flawlessly.

I assume you are using PSEXEC to run apps on remote computers? What I've done is to send a script to the remote computer using psexec and then have that script do whatever work is needed remotely and send output back to my machine or common location. I did try to get output from psexec, but ran into a weird issue where only a certain amount of bytes would come back. That's when I switched to piping all output from run statements to "clip" or "clipboard" and then using getclip() to retrieve the info. I"m not at work, so I can't send examples of these ideas...

...by the way, it's pronounced: "JIF"... Bob Berry --- inventor of the GIF format

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

I assume you are using PSEXEC to run apps on remote computers? What I've done is to send a script to the remote computer using psexec and then have that script do whatever work is needed remotely and send output back to my machine or common location. I did try to get output from psexec, but ran into a weird issue where only a certain amount of bytes would come back. That's when I switched to piping all output from run statements to "clip" or "clipboard" and then using getclip() to retrieve the info. I"m not at work, so I can't send examples of these ideas...

My scripts that call psexec read only the first line of data. The data is being written to the console, if I remove the $STDOUT_CHILD and $STDERR_CHILD flags , I can pipe the data to a file locally -- but the goal of the project is not to have to have temp files lying around.

I'm trying to execute the following DOS cmd:

psexec \\HOSTNAME  cmd.exe dir /b /s c:\*.txt

from au3:

$host = "\\" & @ComputerName
$file_spec = "*.*"
$drive_spec = @HomeDrive
$cmd = StringFormat("psexec %s cmd.exe /c dir /s/b %s\\%s",$host,$drive_spec,$file_spec)
$foo = Run($cmd,@workingdir,@SW_MAXIMIZE,2+4)
Edited by flyingboz

Reading the help file before you post... Not only will it make you look smarter, it will make you smarter.

Share this post


Link to post
Share on other sites

Did you try StdoutRead()??

Share this post


Link to post
Share on other sites

Sorry just realize what i wrote wouldn't have made sense. There is a function called stdoutread() that reads the output of your

Code $foo = Run($cmd,@workingdir,@SW_MAXIMIZE,2+4)

This is from the Autoit Help

; Demonstrates StdoutRead()
#include <Constants.au3>

$foo = Run(@ComSpec & " /c dir foo.bar", @SystemDir, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)

While 1
    $line = StdoutRead($foo)
    If @error Then ExitLoop
    MsgBox(0, "STDOUT read:", $line)
Wend

While 1
    $line = StderrRead($foo)
    If @error Then ExitLoop
    MsgBox(0, "STDERR read:", $line)
Wend

MsgBox(0, "Debug", "Exiting...")

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

There is a function called stdoutread() that reads the output of your

emphasis added.

...I can read the first line only with scripts that process other commands flawlessly.

While I omitted for the sake of brevity the call to my subroutine that parses and formats my output, the subroutine works with no known bugs except with the output of psexec. Of course, the topic title may also have been a clue. Edited by flyingboz

Reading the help file before you post... Not only will it make you look smarter, it will make you smarter.

Share this post


Link to post
Share on other sites

;sample command lines -- 
$cmd = "netstat -a -n"                          ;console app  WORKS
;$cmd = @ComSpec & " /c dir /s/b c:\*.txt"      ;using comspec /c WORKS
;replace HOSTNAME with a valid machine , if c:\ doesn't exist on your system,
;you could replace the directory / file spec with %windir%\*.*
;testing requires psexec.exe from sysinternals.com
;$cmd = "psexec \\HOSTNAME cmd.exe /c dir /s/b c:\*.* "      ;using psexec - fails          ?????
$foo = Run($cmd,@workingdir,@SW_MAXIMIZE,2+4)

cwl($foo)
local $result = ""
local $error = 0 
while Not $error
    $block_size = _PeekConsole($foo)
    if @error then   
        cwl('returned error from peekconsole',@error)
        ExitLoop
    EndIf
    
    if $block_size < 0 then cwl('block size negative',$block_size)
    
    if $block_size > 0 then 
        
        $result  &= StdOutRead($foo,$block_size)
        $error = @error
        cwl('reading blocksize',$block_size,StringLen($result),$error)
    EndIf

WEnd

cwl('result',$result)


Func _PeekConsole($process_handle)
    Local $num_bytes_avail = StdOutRead($process_handle,0,True)
        if @error = 0 then 
            Return $num_bytes_avail
        Else
            return SetError(@Error,1,0)
        EndIf
                    
EndFunc

func cwl($s1='',$s2='',$s3='',$s4='')
    consolewrite($s1 & @TAB & $s2 & @TAB & $s3 & @TAB & $s4 & @LF)
EndFunc


Func _PeekConsole($process_handle)
    Local $num_bytes_avail = StdOutRead($process_handle,0,True)
        if @error = 0 then 
            ;do nothing
        Else
            return SetError(@Error,1,0)
        EndIf
                    
    Return $num_bytes_avail
EndFunc


Reading the help file before you post... Not only will it make you look smarter, it will make you smarter.

Share this post


Link to post
Share on other sites

In the interests of generating a solution, I have punted the use of StdOutRead() and rewritten the functionality using temp files as semaphores.

I'm not sure what's causing the apparent blocking operation I am seeing. I don't know if it's a 'bug' in the console commands or if psexec is doing something really funky with stdout/stderr.


Reading the help file before you post... Not only will it make you look smarter, it will make you smarter.

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

try psexec with -s

Thanks for the suggestion - have tried that. The issue is not the account or permissions, but rather the way psexec handles routing stdout/stderr when invoking the remote COMSPEC.

I went over to the sysinternals forums, and discovered that I am only the latest in a long line who have been fighting with this breakage of psexec. I have found and successfully tested a bsd licensed utility called remcom that successfully handles cmd.exe functions, like dir , etc. It's not as elegant with the way it handles permissions, nor does it have some of the fluffier functionality, but it seems to be solid, and stdout and stderr work as expected.

from remocom /?

Remote Command Executor

Copyright 2006 The WiseGuyz [ http://talhatariq.wordpress.com ]

Author: Talha Tariq [talha.tariq@gmail.com]

Edited by flyingboz

Reading the help file before you post... Not only will it make you look smarter, it will make you smarter.

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