Using StandardOutput.ReadLine()

kingtam2000

Active member
Joined
Jul 12, 2005
Messages
25
Programming Experience
1-3
How does one use the StandardOutput.ReadLine() in real time? Everytime I use it, it gets blocked until the program closes. I have tried flushing the base stream every second, but that seems to have little effect. Any help would be much appreciated. The program in question, if it would help, is vshadow.exe, which is part of the SDK of Volume Shadow Copy Service.

Thanks,
kingtam2000
 
Unfortunately, it appears your method does not seem to be working, if it was intended for reading lines while the program is executing. It continues to block until the program closes. Here is the code I have used to run the program:

VB.NET:
                    Dim args As String = "-wait"

                    For Each drive As String In drives
                        args &= " " & drive.Substring(0, 2)
                    Next
                    Dim info As New ProcessStartInfo("vshadow.exe", args)
                    info.RedirectStandardOutput = True
                    info.UseShellExecute = False
                    info.CreateNoWindow = False
                    proc = New Process()
                    proc.StartInfo = info
                    proc.Start()
                    Dim line As String
                    Dim StdOutput As StreamReader = proc.StandardOutput
                    Do
                        line = StdOutput.ReadLine()
                    Loop Until line.Contains("Press <ENTER> to continue...")
The reason why I have set info.CreateNoWindow to false is that I have to close the vshadow.exe manually becuase it blocks the thread. If this could be what is causing it, I could try turning it back to true, although it seems unlikely. Also, would it be a factor that the code is running on a separate thread to the main form?

As you can see, I need the lines in real time so that I can perform some operations while the program is waiting for the Enter.

Thanks for the reply
 
It works for me for live feed (sort of, sometimes...), but not with CreateNoWindow=False, and using ReadToEnd works better usually. Try running the command though the command interpreter cmd.exe: Dim info As New ProcessStartInfo("cmd.exe", "/c vshadow.exe /args")
If you need to input you must RedirectStandardInput also.
 
Unfortunately, it stills does not seem to be working. The ReadLine continues to block until the program closes. Is there another method besides ReadLine that would work?

Thanks,
kingtam2000

Here's the revised code, if it helps:
VB.NET:
                    Dim args As String = "-wait"

                    For Each drive As String In drives
                        args &= " " & drive.Substring(0, 2)
                    Next
                    Dim info As New ProcessStartInfo("cmd.exe", "/c vshadow.exe " & args)
                    info.RedirectStandardOutput = True
                    info.RedirectStandardInput = False
                    info.UseShellExecute = False
                    info.CreateNoWindow = True
                    info.WorkingDirectory = Application.StartupPath
                    proc = New Process()
                    proc.StartInfo = info
                    proc.Start()
                    Dim line As String
                    Dim StdOutput As StreamReader = proc.StandardOutput
                    Do
                        line &= StdOutput.ReadLine() & vbCrLf
                        If line Is Nothing Then
                            Exit Do
                        End If
                    Loop Until line.Contains("Press <ENTER> to continue...")
 
I downloaded the SDK and ran it through cmd.exe, I get output if I don't use the -wait switch.

There is also another problem with your code "If line Is Nothing... Exit Do". If you run vshadow.exe from command prompt you will see the output starts with a formatting linefeed. When this is read with ReadLine you get the line string excluding the linefeed char, in other words an empty string "" which equals to Nothing for String data type. So you are exiting the reading loop before vshadow gets to write anything.

A problem with ReadLine and While p.HasExited is that text still in stream don't get read, usually seen for long output. I can only see this can be solved by adding a ReadToEnd after process had exited.
 
Thanks for trying to understand the problem. Did you get the output in real time? Because I can remotely think of suspending the process at a certain point.

And about the "If line Is Nothing", from my experience the String data type can be be Nothing, which I am fairly sure is not "" because if I do:
If Str = "" Then ... on a string that is Nothing, I get a NullReferenceException, which doesn't happen with when Str = "", although Convert.ToString(Nothing) = "".

Thanks very much,
kingtam2000
 
Hey, that works nice, I tested with wrong operator ("" = Nothing, instead of "" Is Nothing), that makes it a better loop than HasExited.
 
Back
Top