Discussion:
Get result from shell command?
(too old to reply)
Massi
2008-03-30 16:10:14 UTC
Permalink
Hi all,
i was wondering if there is a way to get the result from a command line
execution with VBS.
I mean, can i call with VBS something like "ping 192.168.0.1" and print
in VBS the result of the ping? (not the error code, just the result
like 100% packets lost)
Run method is not able to do this, right?

Thanks :)
Pegasus (MVP)
2008-03-30 16:55:29 UTC
Permalink
Post by Massi
Hi all,
i was wondering if there is a way to get the result from a command line
execution with VBS.
I mean, can i call with VBS something like "ping 192.168.0.1" and print in
VBS the result of the ping? (not the error code, just the result like 100%
packets lost)
Run method is not able to do this, right?
Thanks :)
Yes, there is a way, and yes, the Run method can do it, as can
the Exec method.


In case you're now wondering HOW to do it, have a look here:
http://www.microsoft.com/technet/scriptcenter/resources/qanda/aug06/hey0817.mspx
Reventlov
2008-03-31 20:45:22 UTC
Permalink
Post by Massi
Hi all,
i was wondering if there is a way to get the result from a command line
execution with VBS.
I mean, can i call with VBS something like "ping 192.168.0.1" and print
in VBS the result of the ping? (not the error code, just the result
like 100% packets lost)
Run method is not able to do this, right?
This is for the programs writing to the standard output:
Set wshshell=CreateObject("wscript.shell")
wshshell.Run "%comspec% /c start /? >c:\help-start.txt"

This uses the stdout stream of the exec method
set ObjExec= WshShell.Exec("sort c:\dir.txt")
msgbox objExec.StdOut.ReadAll

Giovanni
--
Giovanni Cenati (Bergamo, Italy)
Write to user "Reventlov" and domain at katamail com
http://digilander.libero.it/Cenati (Esempi e programmi in VbScript)
--
ekkehard.horner
2008-04-01 06:28:17 UTC
Permalink
Post by Reventlov
Post by Massi
Hi all,
i was wondering if there is a way to get the result from a command line
execution with VBS.
I mean, can i call with VBS something like "ping 192.168.0.1" and print
in VBS the result of the ping? (not the error code, just the result
like 100% packets lost)
Run method is not able to do this, right?
Set wshshell=CreateObject("wscript.shell")
wshshell.Run "%comspec% /c start /? >c:\help-start.txt"
This uses the stdout stream of the exec method
set ObjExec= WshShell.Exec("sort c:\dir.txt")
msgbox objExec.StdOut.ReadAll
Are there any pointers to documentation/evidence that states/proves
that waiting for the .Exec to terminate
Post by Reventlov
set ObjExec = WshShell.Exec("sort c:\dir.txt")
Do While ObjExec.Status = cnWshRunning
WScript.Sleep 100
Loop
Post by Reventlov
msgbox objExec.StdOut.ReadAll
isn't necessary?
Tom Lavedas
2008-04-01 14:21:41 UTC
Permalink
Post by ekkehard.horner
Post by Reventlov
Post by Massi
Hi all,
i was wondering if there is a way to get the result from a command line
execution with VBS.
I mean, can i call with VBS something like "ping 192.168.0.1" and print
in VBS the result of the ping? (not the error code, just the result
like 100% packets lost)
Run method is not able to do this, right?
Set wshshell=CreateObject("wscript.shell")
wshshell.Run "%comspec% /c start /? >c:\help-start.txt"
This uses the stdout stream of the exec method
set ObjExec= WshShell.Exec("sort c:\dir.txt")
msgbox objExec.StdOut.ReadAll
Are there any pointers to documentation/evidence that states/proves
that waiting for the .Exec to terminate
Post by Reventlov
set ObjExec = WshShell.Exec("sort c:\dir.txt")
Do While ObjExec.Status = cnWshRunning
WScript.Sleep 100
Loop
Post by Reventlov
msgbox objExec.StdOut.ReadAll
isn't necessary?
I suspect it's not documented, but one characteristic of the ReadAll
in this application is that it waits for an end-of-file indication.
Though I don't know what that is exactly, it is obvious that it occurs
when the Exec process completes. So, with this particular
implementation the Do loop is redundant.

One problem with this approach is that errors in the underlying
process can fill the StdErr buffer and block processing. WinZip is
infamous for doing this. And because the ReadAll of the StdOut is in
control, there is no way to unblock the StdErr buffer. Putting the
StdErr with a ReadAll before the StdOut read results in it taking
control, instead. The best approach, I think is to put a ReadLine for
each port and process them in the wait loop.

Tom Lavedas
===========
http://members.cox.net/tglbatch/wsh/
Paul Randall
2008-04-01 15:10:42 UTC
Permalink
Post by Tom Lavedas
Post by ekkehard.horner
Il giorno Sun, 30 Mar 2008 18:10:14 +0200, Massi
Post by Massi
Hi all,
i was wondering if there is a way to get the result from a
command line
execution with VBS.
I mean, can i call with VBS something like "ping 192.168.0.1" and print
in VBS the result of the ping? (not the error code, just the result
like 100% packets lost)
Run method is not able to do this, right?
Set wshshell=CreateObject("wscript.shell")
wshshell.Run "%comspec% /c start /? >c:\help-start.txt"
This uses the stdout stream of the exec method
set ObjExec= WshShell.Exec("sort c:\dir.txt")
msgbox objExec.StdOut.ReadAll
Are there any pointers to documentation/evidence that states/proves
that waiting for the .Exec to terminate
set ObjExec = WshShell.Exec("sort c:\dir.txt")
Do While ObjExec.Status = cnWshRunning
WScript.Sleep 100
Loop
msgbox objExec.StdOut.ReadAll
isn't necessary?
I suspect it's not documented, but one characteristic of the ReadAll
in this application is that it waits for an end-of-file indication.
Though I don't know what that is exactly, it is obvious that it occurs
when the Exec process completes. So, with this particular
implementation the Do loop is redundant.
One problem with this approach is that errors in the underlying
process can fill the StdErr buffer and block processing. WinZip is
infamous for doing this. And because the ReadAll of the StdOut is in
control, there is no way to unblock the StdErr buffer. Putting the
StdErr with a ReadAll before the StdOut read results in it taking
control, instead. The best approach, I think is to put a ReadLine for
each port and process them in the wait loop.
In my distant W98 past with much less real and virtual memory, I
recall problems that could have been due to a full StdStream buffer.
With 1 GB of real memory and 'lots' of virtual memory, how big can the
StdIn, StdOut, and StdErr buffers be, and can you see them filling up
by watching the WScript process' Mem Usage in Task Manager? I have
had no problems with doing a ReadAll of a 16 MB directory listing, but
I can understand how a runaway error can dump vastly more into the
StdErr buffer.

Do you know of a sample script we can download that demonstrates the
problem, and perhaps even demonstrates good handling to overcome the
problem?

-Paul Randall
Tom Lavedas
2008-04-01 17:08:23 UTC
Permalink
Post by Paul Randall
Post by Tom Lavedas
Post by ekkehard.horner
Il giorno Sun, 30 Mar 2008 18:10:14 +0200, Massi
Post by Massi
Hi all,
i was wondering if there is a way to get the result from a command line
execution with VBS.
I mean, can i call with VBS something like "ping 192.168.0.1" and print
in VBS the result of the ping? (not the error code, just the result
like 100% packets lost)
Run method is not able to do this, right?
Set wshshell=CreateObject("wscript.shell")
wshshell.Run "%comspec% /c start /? >c:\help-start.txt"
This uses the stdout stream of the exec method
set ObjExec= WshShell.Exec("sort c:\dir.txt")
msgbox objExec.StdOut.ReadAll
Are there any pointers to documentation/evidence that states/proves
that waiting for the .Exec to terminate
set ObjExec = WshShell.Exec("sort c:\dir.txt")
Do While ObjExec.Status = cnWshRunning
WScript.Sleep 100
Loop
msgbox objExec.StdOut.ReadAll
isn't necessary?
I suspect it's not documented, but one characteristic of the ReadAll
in this application is that it waits for an end-of-file indication.
Though I don't know what that is exactly, it is obvious that it occurs
when the Exec process completes. So, with this particular
implementation the Do loop is redundant.
One problem with this approach is that errors in the underlying
process can fill the StdErr buffer and block processing. WinZip is
infamous for doing this. And because the ReadAll of the StdOut is in
control, there is no way to unblock the StdErr buffer. Putting the
StdErr with a ReadAll before the StdOut read results in it taking
control, instead. The best approach, I think is to put a ReadLine for
each port and process them in the wait loop.
In my distant W98 past with much less real and virtual memory, I
recall problems that could have been due to a full StdStream buffer.
With 1 GB of real memory and 'lots' of virtual memory, how big can the
StdIn, StdOut, and StdErr buffers be, and can you see them filling up
by watching the WScript process' Mem Usage in Task Manager? I have
had no problems with doing a ReadAll of a 16 MB directory listing, but
I can understand how a runaway error can dump vastly more into the
StdErr buffer.
Do you know of a sample script we can download that demonstrates the
problem, and perhaps even demonstrates good handling to overcome the
problem?
-Paul Randall
Surprisingly, the developers made these fixed length and fairly small
(8 kbytes). I mentioned Winzip as an application that I have seen
cause this problem because it uses StdErr to show progress. Here is a
thread that illustrates the point:

http://www.google.com/groups?threadm=034a01c3b2d7%248a431230%24a501280a%40phx.gbl

Tom Lavedas
===========
http://members.cox.net/tglbatch/wsh/
Paul Randall
2008-04-01 19:48:25 UTC
Permalink
Post by Tom Lavedas
Post by Paul Randall
Post by Tom Lavedas
Post by ekkehard.horner
Il giorno Sun, 30 Mar 2008 18:10:14 +0200, Massi
Post by Massi
Hi all,
i was wondering if there is a way to get the result from a command line
execution with VBS.
I mean, can i call with VBS something like "ping 192.168.0.1" and print
in VBS the result of the ping? (not the error code, just the result
like 100% packets lost)
Run method is not able to do this, right?
Set wshshell=CreateObject("wscript.shell")
wshshell.Run "%comspec% /c start /? >c:\help-start.txt"
This uses the stdout stream of the exec method
set ObjExec= WshShell.Exec("sort c:\dir.txt")
msgbox objExec.StdOut.ReadAll
Are there any pointers to documentation/evidence that
states/proves
that waiting for the .Exec to terminate
set ObjExec = WshShell.Exec("sort c:\dir.txt")
Do While ObjExec.Status = cnWshRunning
WScript.Sleep 100
Loop
msgbox objExec.StdOut.ReadAll
isn't necessary?
I suspect it's not documented, but one characteristic of the ReadAll
in this application is that it waits for an end-of-file
indication.
Though I don't know what that is exactly, it is obvious that it occurs
when the Exec process completes. So, with this particular
implementation the Do loop is redundant.
One problem with this approach is that errors in the underlying
process can fill the StdErr buffer and block processing. WinZip is
infamous for doing this. And because the ReadAll of the StdOut
is
in
control, there is no way to unblock the StdErr buffer. Putting the
StdErr with a ReadAll before the StdOut read results in it taking
control, instead. The best approach, I think is to put a
ReadLine
for
each port and process them in the wait loop.
In my distant W98 past with much less real and virtual memory, I
recall problems that could have been due to a full StdStream
buffer.
With 1 GB of real memory and 'lots' of virtual memory, how big can the
StdIn, StdOut, and StdErr buffers be, and can you see them filling up
by watching the WScript process' Mem Usage in Task Manager? I have
had no problems with doing a ReadAll of a 16 MB directory listing, but
I can understand how a runaway error can dump vastly more into the
StdErr buffer.
Do you know of a sample script we can download that demonstrates the
problem, and perhaps even demonstrates good handling to overcome the
problem?
-Paul Randall
Surprisingly, the developers made these fixed length and fairly small
(8 kbytes). I mentioned Winzip as an application that I have seen
cause this problem because it uses StdErr to show progress. Here is a
http://www.google.com/groups?threadm=034a01c3b2d7%248a431230%24a501280a%40phx.gbl
Thanks for the link. Is the WZZip.exe a standalone executable that
can be run on a system without installing the Winzip package? I don't
currently have Winzip installed because I don't know what hooks, like
context menus, it installs and may not uninstall if I don't like it.
The link also talked about the 8KB buffer length. That 8K number
certainly doesn't apply to StdOut on my WXP system.

This little script:
Set oWS = WScript.CreateObject("WScript.Shell")
Set oExec = oWS.exec("%comspec% /c Dir /a /s c:\*.*")
sResults = oExec.stdOut.ReadAll
MsgBox Len(sResults) & vbCrLf & sResults
WScript.Quit

has an message box that starts:
19979638
Volume in drive C is PP01
Volume Serial Number is 3E13-1C01

19979638 is way bigger than an 8K buffer would allow -- maybe 8K is a
W98 or a vintage WScript.Shell limitation. I watched the mem usage in
task manager grow to about 42 megabytes while the dir command in the
script above was running. When the message box showed up, the memory
usage jumped to about 83 megabytes.

-Paul Randall
Tom Lavedas
2008-04-01 20:28:16 UTC
Permalink
Post by Paul Randall
Post by Tom Lavedas
Il giorno Sun, 30 Mar 2008 18:10:14 +0200, Massi
{snip}
Post by Paul Randall
Post by Tom Lavedas
Surprisingly, the developers made these fixed length and fairly small
(8 kbytes). I mentioned Winzip as an application that I have seen
cause this problem because it uses StdErr to show progress. Here is a
http://www.google.com/groups?threadm=034a01c3b2d7%248a431230%24a50128...
Thanks for the link. Is the WZZip.exe a standalone executable that
can be run on a system without installing the Winzip package? I don't
currently have Winzip installed because I don't know what hooks, like
context menus, it installs and may not uninstall if I don't like it.
The link also talked about the 8KB buffer length. That 8K number
certainly doesn't apply to StdOut on my WXP system.
Set oWS = WScript.CreateObject("WScript.Shell")
Set oExec = oWS.exec("%comspec% /c Dir /a /s c:\*.*")
sResults = oExec.stdOut.ReadAll
MsgBox Len(sResults) & vbCrLf & sResults
WScript.Quit
19979638
Volume in drive C is PP01
Volume Serial Number is 3E13-1C01
19979638 is way bigger than an 8K buffer would allow -- maybe 8K is a
W98 or a vintage WScript.Shell limitation. I watched the mem usage in
task manager grow to about 42 megabytes while the dir command in the
script above was running. When the message box showed up, the memory
usage jumped to about 83 megabytes.
-Paul Randall
It's been years since I played with this. AFAIK, Wzzip.exe is only
downloadable to registered/licensed users of Winzip. I don't know if
it is loadable without the Winzip install. I suspect not - that it is
just a command line wrapper for the Winzip dlls - but I have never
considered it before.

As far as the apparent lack of a buffer restriction, all I can say is
it was there once and as I said earlier, its been a while since I
considered the question.

Still, a ReadAll would still be a problematic approach, I think,
because a run away application would still be out of reach for the
calling application to intercede.

At this point, we have wondered more than a bit off topic. Fun, but
more time than I can spare at the moment.

Tom Lavedas
===========
http://members.cox.net/tglbatch/wsh/

Loading...