Reading Progress from Command Prompt

Arokh

Well-known member
Joined
Apr 11, 2006
Messages
124
I use a Cmd Prompt app (AVDump) which hashes and gets info from a video file (~200MB), which of course takes some time.
While the App processes the file, it prints the progress into the cmd prompt,
which I want to read into my App.

Now I already achieved to read the line necessary from the cmd prompt,
but with a huge delay, to be more exact, after the hashing is done.

Since AVDump drives the CPU usage to 100%, I thought lowering the priority would solve the problem but it didnt.

Here is the code I use:
PHP:
Public Class AVDump
    Dim CmdOutPut As IO.StreamReader
    Dim CmdProcess As New Process
    Dim Reader As New Threading.Thread(AddressOf ReadProgress)

    Private Sub ReadProgress()
        Do Until CmdProcess.HasExited
            Debug.Print(CmdOutPut.ReadLine)
        Loop
    End Sub

    Public Sub StartAVDump(ByVal CmdLine As String)
        CmdProcess.StartInfo.FileName = My.Application.Info.DirectoryPath & "\AVDump\avdump.exe"
        CmdProcess.StartInfo.RedirectStandardOutput = True
        CmdProcess.StartInfo.UseShellExecute = False

        CmdProcess.Start()
        CmdProcess.PriorityClass = ProcessPriorityClass.BelowNormal

        CmdOutPut = CmdProcess.StandardOutput

        Reader.Start()
    End Sub
End Class

Is there any way to get the progress in realtime?

The aguments to AVDump:
"-log:log.xml -ay " & Chr(34) & "[VIDEOFILE(AVI;MPG;MP4;MKV;OGM)]" & Chr(34)
 
StreamReader may buffer

The StreamReader class may be performing internal buffering. Rather than using CmdOutPut.ReadLine followed by Debug.Print, perhaps you could try using CmdOutPut.Read followed by Debug.Write (as the line seperators would also transfer):

Code:
Private Sub ReadProgress() 
    Dim buff As Char()
    Dim numRead As Integer

    buff = New Char(4096) Default stream buffer size

    Do Until CmdProcess.HasExited 
        Attempt to read some text
        numRead = CmdOutPut.Read(buff, 0, buff.Length)

        If (numRead > 0) Then
            Write text to Debug
            Debug.Write(New String(buff, 0, numRead))
        End If
    Loop 
End Sub

Good luck :)
 
Unfortunately, this didnt solve the problem.
Although I had to change the code a little, but I guess it is the same:
Code:
Dim buff(4096) As Char
Dim numRead As Integer

Do Until CmdProcess.HasExited
...
The Procedure "stops" on numRead = CmdOutPut.Read(buff, 0, buff.Length)
until the Hashing of the file is complete.

After that it outputs the first line printed
(which should have been printed directly after the cmd prompt was started)
till the last or somewhere in the middle,
since the cmd is closed right after the hashing is done
and HasExited is true before all the old lines could be printed.

So I guess that means the StreamReader is still buffering.
I also tried to lower the CharArray with no luck.
Any other ideas?

And I forgot to say that in addition to the heavy load on the CPU the cmd prompt outputs ~4 lines per second.
But it is not important to get all of them, if I could get the lines in realtime this way.
 
Reading directly from Stream

You could try reading directly from the Stream which the StreamReader is reading from:

Code:
Import System.IO, System.Text and System.Threading

Private Sub ReadProgress()
    Dim buff As Byte()
    Dim numRead As Integer

    buff = New Byte(4095) Default stream buffer size

    Do Until CmdProcess.HasExited
        Attempt to read some text
        numRead = CmdOutPut.BaseStream.Read(buff, 0, buff.Length)

        While (numRead > 0)
            Write text to Debug
            Debug.Write(Encoding.Default.GetString(buff, 0, numRead))
            Attempt to read more text
            numRead = CmdOutPut.BaseStream.Read(buff, 0, buff.Length)
        End While

        Thread.Sleep(1) Dont hog the CPU
    Loop
End Sub

Try it and see. Good luck :)
 
Re: Reading directly from Stream

you could also try and sleep the thread for 0(zero) which will cause it to yeild and it will help stop the hammering on the processor
 
Back
Top