Page 1 of 1

Sysinternals' PsExec with RunProgram()

Posted: Thu Jan 11, 2007 12:05 am
by Clutch
Has anyone here been able to successfully use ReadProgramString() to obtain the output from PsExec on having launched it with RunProgram()? The code I've been testing with is what's given in the PB helpfile under RunProgram(), and I've changed it as follows to use PsExec to run ipconfig:

Code: Select all

program$ = "<PATH_TO>\psexec.exe"
params$  = "\\<REMOTE_COMPUTER> -u <USERNAME> -p <PASSWORD> -e ipconfig /all"
;
Compiler = RunProgram(program$, params$, "", #PB_Program_Open|#PB_Program_Read)
Output$ = ""
If Compiler  
  While ProgramRunning(Compiler)
    Output$ + ReadProgramString(Compiler) + Chr(13)
  Wend
  Output$ + Chr(13) + Chr(13)
  Output$ + "Exitcode: " + Str(ProgramExitCode(Compiler))     
EndIf
MessageRequester("Output", Output$)
The result is that the console window stays open indefinitely, and upon closing it manually after waiting a suitable amount of time, the output given in the messagebox is only about half of the information normally returned by ipconfig. When the parameter passed to PsExec is "/?", the messagebox shows the entire contents of what would have been displayed in the console window.

Any info would be greatly appreciated! :)

response

Posted: Thu Jan 11, 2007 10:22 am
by burnix
have you tried that :

Compiler = RunProgram(program$, params$, "", #PB_Program_Open|#PB_Program_Read|#PB_Program_Hide)

the param #PB_Program_Hide dont show the console windows

Posted: Thu Jan 11, 2007 4:57 pm
by Clutch
burnix, thanks for the reply. I had already tried it with the #PB_Program_Hide flag before having arrived at the snip I posted, but the effect was that I couldn't end the hanging PsExec process except through Task Manager. I don't know enough to determine if this is a limitation with PsExec in being able to redirect its output or if it's a problem with how PB handles the redirecting (or if it's just my bad/inept coding). :?

ah ok

Posted: Thu Jan 11, 2007 5:39 pm
by burnix
ah ok. I have the solution (i work on this 2 week ago). Try this :

Code: Select all

Pid = RunProgram("toto.exe", "-endpos..............
at the end of the prog paste this

Code: Select all

KillProgram(Pid) 
CloseProgram(Pid)
Or try this

Code: Select all

Repeat 
Pid = RunProgram("toto.exe", "params", "", #PB_Program_Hide|#PB_Program_Open|#PB_Program_Read) 

Repeat 
  Select WaitWindowEvent(10) 
    Case #PB_Event_CloseWindow 
      Break 
  EndSelect 
    
    
    SetGadgetText(#Editor,ReadProgramString(Pid))

ForEver 

KillProgram(Pid) 
CloseProgram(Pid)

or this

Code: Select all

Enumeration
  #Editor
EndEnumeration

OpenWindow(0, 0, 0, 512, 384, "", #PB_Window_ScreenCentered | #PB_Window_SystemMenu) 
CreateGadgetList(WindowID(0)) 
TextGadget(#Editor, 10, 10, 492, 364,"",#PB_Text_Right)


Pid = RunProgram("toto.exe", "param", "", #PB_Program_Hide|#PB_Program_Open|#PB_Program_Read) 

While ProgramRunning(Pid) 
  Select WaitWindowEvent(10) 
    Case #PB_Event_CloseWindow 
      Break 
  EndSelect 
    
    
    SetGadgetText(#Editor,ReadProgramString(Pid))

Wend 

KillProgram(Pid) 
CloseProgram(Pid)

Posted: Thu Jan 11, 2007 5:46 pm
by Max
Instead:

Code: Select all

If Compiler 
  While ProgramRunning(Compiler)
    Output$ + ReadProgramString(Compiler) + Chr(13)
  Wend
  Output$ + Chr(13) + Chr(13)
  Output$ + "Exitcode: " + Str(ProgramExitCode(Compiler))     
EndIf 
You must try:

Code: Select all

If Compiler 
  While ProgramRunning(Compiler)
    While AvailableProgramOutput(Compiler)
      Output$ + ReadProgramString(Compiler) + Chr(13)
    Wend
  Wend
  Output$ + Chr(13) + Chr(13)
  Output$ + "Exitcode: " + Str(ProgramExitCode(Compiler))     
  CloseProgram(Compiler)
EndIf 
Enjoy.

Posted: Thu Jan 11, 2007 6:41 pm
by Clutch
Thank you both for your replies. Unfortunately, none of the examples given solve the issue. :(

@burnix
The Kill/CloseProgram() lines are never reached when PsExec is set to actually execute a remote process (ipconfig in my case). The Repeat...ForEver block in your first example causes the PB window itself to hang, and the While ProgramRunning() in the second runs indefinitely for as long as the psexec.exe process is running. When PsExec is called without any parameters, it displays its help screen, and when it's called from RunProgram(), everything runs as it should; the entire contents of the help is displayed, and the process terminates on its own. The problem comes into play when PsExec executes the remote process, as only partial output (of the remote process) is displayed, and PsExec itself runs forever.

@Max
The situation with your example is the same as I described above. The While ProgramRunning() block will loop forever if I don't manually close PsExec whenever it's executing a remote process. As I mentioned, if PsExec is called without any parameters such as to display its syntax usage, all of the output is displayed properly, and it terminates normally.

Posted: Fri Jan 12, 2007 12:47 am
by Clutch
Update:
After some exhaustive Googling, it would seem that this is an issue with the way PsExec operates. On the Sysinternals forum alone there were many threads dealing with problems in trying to redirect PsExec's stdout using several different languages, and no one was able to devise a viable solution. I had even attempted using API directly with some code by Rings posted on this forum, but it gives the same result as using RunProgram()/ReadProgramString().

Thanks again to burnix and Max for your replies.

Posted: Sun Sep 21, 2008 10:44 pm
by Amundo
Better late than ever!

I was also trying to get PSEXEC to execute "ipconfig /all" on a remote server, and it would just hang...

The only way around it is to set the compile option to produce a console app not a windows one.

HTH