Set FSO = CreateObject("Scripting.FileSystemObject")
Set Shell = CreateObject("WScript.Shell")
Set TextStream = FSO.CreateTextFile("C:\backup.txt")
TextStream.WriteLine("Backup of hostname at: " & now)
TextStream.WriteBlankLines(2)
TextStream.WriteLine("Zip operation beginning")
Zipfile = datepart("yyyy", today) & datepart("m", today) &
datepart("d", today) & ".zip"
Set Cmd = Shell.Exec("c:\Program Files\Winzip\wzzip.exe -r -p e:\" &
Zipfile & " " & folder)
' if the following line is commented out the script works.
' otherwise it hangs the script and it never completes
result = Cmd.StdOut.ReadAll()
TextStream.WriteLine(result)
set Cmd = nothing
Set Shell = nothing
TextStream.Close
set FSO = Nothing
If I try and capture the StdOut the logfile (backup.txt) is created
and contains about 10 lines of the StdOut of the command. Thinking
it's trying to capture the StdOut before completion of the script and
that's causing it to hang I tried adding a
Do While Cmd.Status = 0
Wsh.Sleep 1000
Loop
before the result = Cmd.StdOut.ReadAll() to have the script wait for
the completion of the command but no luck. The same problem happened.
Any suggestions would be greatly appreciated.
Set FSO = CreateObject("Scripting.FileSystemObject")
Set Shell = CreateObject("WScript.Shell")
Set TextStream = FSO.CreateTextFile("C:\backup.txt")
TextStream.WriteLine("Backup of hostname at: " & now)
TextStream.WriteBlankLines(2)
TextStream.WriteLine("Zip operation beginning")
TextStream.Close
Zipfile = Year(Now) & Month(Now) & Day(Now) & ".zip"
sCmd = """c:\Program Files\Winzip\wzzip.exe"" -r -p e:\" _
& Zipfile & " " & folder & " >>c:\backup.txt"
nRes = Shell.Run("%comspec% /c " & sCmd)
Set Shell = nothing
TextStream.Close
set FSO = Nothing
wsh.echo "Done"
Tom Lavedas
===========
>.
>
on error resume next
do until exec.StdErr.AtEndofStream and exec.StdOut.AtEndOfStream
wscript.sleep 10
WScript.StdErr.WriteLine exec.StdErr.ReadLine
WScript.StdOut.WriteLine exec.StdOut.ReadLine
loop
Apparently StdOut has an 8000 byte buffer size limit. In order to get
anything more than that from it you need to pull from it before it
fills up. If the buffer fills up it hangs whatever process is writing
to StdOut. It's detailed in this newsgroup post
http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&selm=uVGoh2gRBHA.1904%40tkmsftngp05
and this msdn article
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnclinic/html/scripting11132000.asp
(search for amazing). The workaround is to do what Alex outlined below
which is to constantly read from StdOut until the process is finished.
I haven't gotten it to work yet but if I do I'll post working code.
This is VERY frustrating.
Mark DuPrey
With that bit of knowledge, I've constructed something
that works for me ...
Set FSO = CreateObject("Scripting.FileSystemObject")
Set Shell = CreateObject("WScript.Shell")
Set TextStream = FSO.CreateTextFile("C:\backup.txt")
TextStream.WriteLine("Backup of hostname at: " & now)
TextStream.WriteBlankLines(2)
TextStream.WriteLine("Zip operation beginning")
Zipfile = Year(Now) & Month(Now) & Day(Now) & ".zip"
folder = "."
sCmd = "c:\Program Files\Winzip\wzzip.exe -r -p c:\" _
& Zipfile & " " & folder
set Cmd = Shell.Exec(sCmd)
Do Until Cmd.StdOut.AtEndofStream
result = result & Cmd.StdOut.Read(1)
if Not Cmd.StdErr.AtEndofStream Then _
result = result & Cmd.StdErr.Read(1)
Loop
TextStream.Write result
set Cmd = nothing
Set Shell = nothing
TextStream.Close
set FSO = Nothing
wsh.echo "Done"
I think this could still run into trouble in some instance
because the 'read loop' is NOT fast enough to keep the
buffer empty. That is, some text remained in the StdOut
buffer after the Exec process was ended. The procedure
above reads it all, but quite a few bytes remained in the
buffer after the Wzzip.exe process had ended in my testing
in a folder with 201 short text files.
In addition, the script above puts all of the StdErr text
into the Result stream. Change the .StdErr.Read(1) to a
Skip(1) to see the difference.
Tom Lavedas
===========
>.
>
> I'm trying to write a simple backup script. I'd like to use wsh.exec
> to run the command line Winzip to create a zip file and capture the
> StdOut and write it to a log. It works just fine as long as I don't
> try and capture the StdOut of the command line Winzip component. In
> the script below E: is a local drive containing the folder to be
> backed up. The problem is commented in the code.
On Win98 my scripts used to hang for some Exec.StdOut.ReadAll()-Operations,
mostly those using command.com /c <some_cmdlinetool>.
While others - mostly Win32-CmdLine Exes- like ping.exe - worked well
ReadAll() expects an EndOfStream-Signal otherwise it will eternally
hang, waiting for EOF, even if the WshExec is terminated (status == 1).
To my opion there is a bug in signaling the EndOfStream-Signal
from command.com to the WshExec-TextStream.
If you're running your script on NT or later, of course, this can not be
the reason.
On the other hand "wzzip.exe" seems to use special streams, since you can't
pipe an "Enter" into its StdIn-Stream if you're using the unregistered
version, which displays an "This is shareware, please Register and press any
key"-Screen before starting the zip operation (This results in a hanging
script aswell, because Exec.Stdin.Write <any char> won't work.
wzzip somehow realizes that the key is send programmatically, not manually)
I switched to winrar for unzipping zipped F-Prot signatures, because
rar.exe doesn't display nasty Shareware-Reminders before doing work ;-)
--
Gruesse, Alex
Tom Lavedas
===========
PS. Alex, is this what you were asking about over in .vbscript?
"Tom Lavedas" <tlav...@hotmail.remove.com> wrote in message news:<67a301c3b388$86b57930$a601...@phx.gbl>...
> I had been exploring the issue of reading the output
> incrementally. The part I missed was that Wzzip.exe spews
> unprintable characters to StdErr that need to be processed
> to keep that buffer from overflowing as well.
>
> With that bit of knowledge, I've constructed something
> that works for me ...
{snip}
I tend to redirect output/error to a single file and then read it back using
the Escape() function when I run into situations like that, just to figure
out what the dickens those characters are. Takes some work until you get a
boilerplate script going with it, but then it's fast.