Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
WshScriptExec.Exec
Message
From
23/05/2013 23:54:17
 
 
To
23/05/2013 19:33:20
General information
Forum:
Visual FoxPro
Category:
Other
Environment versions
Visual FoxPro:
VFP 9 SP2
OS:
Windows 7
Application:
Desktop
Miscellaneous
Thread ID:
01574611
Message ID:
01574615
Views:
41
>Anyone have some input on this? I'm trying to run a batch file using the WScript.Shell.Exec command. The issue I'm having is that the batch file writes a good amount of data to STDOUT/STDERR and it appears to be filling up its buffer and hanging. I've read somewhere that each invocation gets a 4K buffer for STDOUT/STDERR. This is the code that I'm using to read from the two streams. Is there a way for me to capture data from the stream so that it doesn't reach the 4k limit?
>
>When I change the batch file to limit its output it runs without issue.
>
>This is my code but it obviously needs to be modified.
>
>Thanks in advance for you help and ideas.
>
>
>* ----------------------------------------------------------------------
>* Run the command
>* ----------------------------------------------------------------------
>This.poWshScriptExec = This.poShell.Exec( tcCMD )
>
>* ----------------------------------------------------------------------
>* Read the output of the shell command thread (STDERR)
>* ----------------------------------------------------------------------
>DO WHILE This.poWshScriptExec.StdErr.AtEndOfStream = .F.
>	lcString = This.poWshScriptExec.StdErr.ReadLine()
>
>	IF EMPTY( lcString ) = .F.
>		lcStdErr = lcStdErr + lcString + CARET_CHAR
>	ENDIF
>	WAIT '' TIMEOUT .1
>ENDDO
>
>* ----------------------------------------------------------------------
>* Read the output of the shell command thread (STDOUT)
>* ----------------------------------------------------------------------
>DO WHILE This.poWshScriptExec.StdOut.AtEndOfStream = .F.
>	lcString = This.poWshScriptExec.StdOut.ReadLine()
>
>	IF EMPTY( lcString ) = .F.
>		lcStdOut = lcStdOut + lcString + CARET_CHAR
>	ENDIF
>	WAIT '' TIMEOUT .1
>ENDDO
>
>* ----------------------------------------------------------------------
>* Check to see if the command is still running.
>* ----------------------------------------------------------------------
>DO WHILE This.poWshScriptExec.Status = 0
>	WAIT WINDOW '' TIMEOUT .1
>ENDDO
>
>lcRetValBuff = IIF( OCCURS( VCS_ERROR_ID_STR, lcStdErr ) = 0, ALLTRIM( STR( This.poWshScriptExec.ExitCode )), ALLTRIM( STR( VCS_FAILURE ))) + PIPE_CHAR
>lcRetValBuff = lcRetValBuff + lcStdErr + PIPE_CHAR + lcStdOut
>
>RETURN lcRetValBuff
>
There is some good info at http://support.microsoft.com/kb/960246

According to that, STDOUT and STDERR are sharing the same 4K buffer. It looks to me, the way you have your code above, it will remain in the STDERR loop until it's .AtEndOfStream. If, in the meantime, STDOUT is also writing to the buffer, it could overflow. To prevent that I'd be inclined to process both streams in the same loop:
DO WHILE This.poWshScriptExec.StdErr.AtEndOfStream = .F. ;
  OR This.poWshScriptExec.StdOut.AtEndOfStream = .F.

  * Read from StdErr
  ...

  * Read from StdOut
  ...

  * At this point your code would
  * WAIT '' TIMEOUT .1
  * I'm not sure that's a good idea. If the batch file writes more than 4K in less than 0.1 seconds
  * you might overflow as well.
  * For test purposes, you could try it with no wait at all.
  * If you want to play nicely with other processes on the same box, you could just issue
  * DOEVENTS

ENDDO
Regards. Al

"Violence is the last refuge of the incompetent." -- Isaac Asimov
"Never let your sense of morals prevent you from doing what is right." -- Isaac Asimov

Neither a despot, nor a doormat, be

Every app wants to be a database app when it grows up
Previous
Reply
Map
View

Click here to load this message in the networking platform