vbscriptstdoutaria2

VBScript - Capturing output from stdout


I know this has been answered one in another question, but I simply do not understand how it is done.

I am trying to get the output of a command line program (Aria2 downloader) into a HTA script so it can be parsed and the download percentage, file size etc can be obtained and updated into a DIV dynamically.

Here is the code I have adjusted and have been trying to use but it just locks up the interface until the command line has finished and THEN displays all the output, instead of displaying it as and when it comes through.

Const WshRunning = 0
Const WshFinished = 1
Const WshFailed = 2
strCommand = "ping.exe 127.0.0.1"

Set WshShell = CreateObject("WScript.Shell")
Set WshShellExec = WshShell.Exec(strCommand)

Do While WshShellExec.Status = WshRunning
    window.setTimeOut "", 100
Loop

Select Case WshShellExec.Status
    Case WshFinished
        strOutput = WshShellExec.StdOut.ReadAll()
    Case WshFailed
        strOutput = WshShellExec.StdErr.ReadAll()
End Select

Set objItem = Document.GetElementByID("status")
    objItem.InnerHTML = "" & strOutput & ""

How do I modify this so that it doesn't lock up my user interface and grabs the output and displays it in the "status" div as it comes through?


Solution

  • The problem is that your code does not end, returning the control to the browser. You don't leave the loop until the program ends and the perceived status is that the interface hangs until the subprocess ends.

    You need to set a callback so the browser will periodically call your code where you will update the status and leave.

    <html>
    <head>
        <title>pingTest</title>
        <HTA:APPLICATION
            APPLICATIONNAME="pingTest"
            ID="pingTest"
            VERSION="1.0"
        />
    </head>
    
    <script language="VBScript">
        Const WshRunning = 0
        Const WshFinished = 1
        Const WshFailed = 2
    
        Dim WshShellExec, Interval
    
        Sub Window_onLoad
            LaunchProcess
        End Sub
    
        Sub LaunchProcess
            Set WshShellExec = CreateObject("WScript.Shell").Exec("ping -n 10 127.0.0.1")
            Interval = window.setInterval(GetRef("UpdateStatus"),500)
        End Sub    
    
        Sub UpdateStatus
        Dim status 
            Set status = Document.GetElementByID("status")
            Select Case WshShellExec.Status
                Case WshRunning
                    status.InnerHTML = status.InnerHTML & "<br>" & WshShellExec.StdOut.ReadLine()
                Case WshFinished, WshFailed
                    status.InnerHTML = status.InnerHTML & "<br>" & Replace(WshShellExec.StdOut.ReadAll(),vbCRLF,"<br>")
                    window.clearInterval(Interval)
                    Interval = Empty
            End Select
        End Sub
    </script>
    
    <body>
        <div id="status"></div>
    </body>
    </html>