Retrieve Process Output as a String

jlwilson

Member
Joined
Jun 23, 2005
Messages
11
Location
Harrison, AR
Programming Experience
Beginner
Ok, here is another doozy for me. I am trying to figure out how to retreive the output of a process in string format. Here is why...

First off, I'm trying to get away from ugly black MS-DOS Windows! Ewww! Secondly, there are times when I'd like to actually parse the output of a command, line for line. For instance, I may want to have a window that allows a user to type in or select a servername to ping. Once they click the ping button, I'd like to be able to parse the data from the ping output so that I can translate strings containing the phrase "Reply from" to "Online" or "Request Timed Out" to "Offline".

I come from a background in Perl as far as my programming capabilities and one thing I like about VB.NET that I didn't like in perl was the ability to create easy to use graphic user interfaces quickly.

If I could figure out how to read in process output as a string, I'm sure it would open up new horizons for me.

Anyone got an idea. The below code is what I tried and many of you may laugh at it, but it shows you how I was thinking.

VB.NET:
[SIZE=2]
[/SIZE][SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] strOutput [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]String
[/COLOR][/SIZE][SIZE=2]Process.Start([/SIZE][SIZE=2][COLOR=#800000]"cmd"[/COLOR][/SIZE][SIZE=2], [/SIZE][SIZE=2][COLOR=#800000]"/c title Pinging "[/COLOR][/SIZE][SIZE=2] & strRouter & [/SIZE][SIZE=2][COLOR=#800000]" &&ping "[/COLOR][/SIZE][SIZE=2] & strRouter & [/SIZE][SIZE=2][COLOR=#800000]" -t"[/COLOR][/SIZE][SIZE=2])
strOutput = Process.Start([/SIZE][SIZE=2][COLOR=#800000]"cmd"[/COLOR][/SIZE][SIZE=2], [/SIZE][SIZE=2][COLOR=#800000]"/c title Pinging "[/COLOR][/SIZE][SIZE=2] & strDigi & [/SIZE][SIZE=2][COLOR=#800000]" &&ping "[/COLOR][/SIZE][SIZE=2] & strDigi & [/SIZE][SIZE=2][COLOR=#800000]" -t"[/COLOR][/SIZE][SIZE=2]).StandardOutput.ReadLine.ToString
[/SIZE][SIZE=2][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=2].TextBox1.Text = strOutput
[/SIZE]

This fails miserably. Basically, I want the ping output to show up in my textbox.
 
Found this...

Shared Function GetProcessText(ByVal process As String, ByVal param As String, ByVal workingDir As String) As String
Dim p As Process = New Process
' this is the name of the process we want to execute
p.StartInfo.FileName = process
If Not (workingDir = "") Then
p.StartInfo.WorkingDirectory = workingDir
End If
.StartInfo.Arguments = param
' need to set this to false to redirect output
p.StartInfo.UseShellExecute = False
p.StartInfo.RedirectStandardOutput = True
' start the process
p.Start
' read all the output
' here we could just read line by line and display it
' in an output window

Dim output As String = p.StandardOutput.ReadToEnd
' wait for the process to terminate
p.WaitForExit
Return output
End Function
 
How would I use this Public Function?

Ok, now I feel stupid. Did I mention I'm a very new beginner haha. How would I implement this cool shared function into my existing form?
 
I'll try;

No need to feel stupid, this is fairly complex and not very common. Just the type of stuff to be asked in forums.


Looks like the author has broken up this line into string variables:

Process.Start("cmd", "/c title Pinging " & strRouter & " &&ping " & strRouter & " -t")

p.StartInfo.FileName = process 'process probably = "cmd"
p.StartInfo.Arguments = param 'param probably = "/c title Pinging " & strRouter & " &&ping " & strRouter & " -t"

he is adding conditions to the process command line here:
p.StartInfo.UseShellExecute = False
p.StartInfo.RedirectStandardOutput = True

if you were doing it all in one line there would be a series of commas and the true and false, but I don't know the order.

Finally,
Dim output As String = p.StandardOutput.ReadToEnd

Once again "p" has been defined previously, so here we are just directing the output to a defined string.
You will be able to search this forum for ways to manipulate the string anyway you want. Search -parse string





 
Help me modify this code to use GetProcessText

Thanks a bunch! It works! I have a "tweaking" question though regarding this function. How would I manipulate my code below so that I could have the process output populate my textbox line by line instead of waiting until it is finished to populate my box? BTW, I hope I'm not pestering you with all these questions. I just can't seem to find these sorts of answers elsewhere in the forum.

VB.NET:
[SIZE=2][COLOR=#0000ff]
Public[/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff]Class[/COLOR][/SIZE][SIZE=2] frmPingUtility
[/SIZE][SIZE=2][COLOR=#0000ff]Private[/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff]Sub[/COLOR][/SIZE][SIZE=2] frmPingUtility_Load([/SIZE][SIZE=2][COLOR=#0000ff]ByVal[/COLOR][/SIZE][SIZE=2] sender [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] System.Object, [/SIZE][SIZE=2][COLOR=#0000ff]ByVal[/COLOR][/SIZE][SIZE=2] e [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] System.EventArgs) [/SIZE][SIZE=2][COLOR=#0000ff]Handles[/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff]MyBase[/COLOR][/SIZE][SIZE=2].Load
[/SIZE][SIZE=2][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=2].txtCenterID.Focus()
[/SIZE][SIZE=2][COLOR=#0000ff]End[/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff]Sub
[/COLOR][/SIZE][SIZE=2][/SIZE][SIZE=2][COLOR=#0000ff]Private[/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff]Sub[/COLOR][/SIZE][SIZE=2] btnCancel_Click([/SIZE][SIZE=2][COLOR=#0000ff]ByVal[/COLOR][/SIZE][SIZE=2] sender [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] System.Object, [/SIZE][SIZE=2][COLOR=#0000ff]ByVal[/COLOR][/SIZE][SIZE=2] e [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] System.EventArgs) [/SIZE][SIZE=2][COLOR=#0000ff]Handles[/COLOR][/SIZE][SIZE=2] btnCancel.Click
[/SIZE][SIZE=2][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=2].Close()
[/SIZE][SIZE=2][COLOR=#0000ff]End[/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff]Sub
[/COLOR][/SIZE][SIZE=2][/SIZE][SIZE=2][COLOR=#0000ff]Private[/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff]Sub[/COLOR][/SIZE][SIZE=2] btnPing_Click([/SIZE][SIZE=2][COLOR=#0000ff]ByVal[/COLOR][/SIZE][SIZE=2] sender [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] System.Object, [/SIZE][SIZE=2][COLOR=#0000ff]ByVal[/COLOR][/SIZE][SIZE=2] e [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] System.EventArgs) [/SIZE][SIZE=2][COLOR=#0000ff]Handles[/COLOR][/SIZE][SIZE=2] btnPing.Click
[/SIZE][SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] strCID [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff]String
[/COLOR][/SIZE][SIZE=2][/SIZE][SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] strRouter [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff]String
[/COLOR][/SIZE][SIZE=2][/SIZE][SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] strDigi [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff]String
[/COLOR][/SIZE][SIZE=2]strCID = [/SIZE][SIZE=2][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=2].txtCenterID.Text
strRouter = [/SIZE][SIZE=2][COLOR=#800000]"router."[/COLOR][/SIZE][SIZE=2] & strCID & [/SIZE][SIZE=2][COLOR=#800000]".af.com"
[/COLOR][/SIZE][SIZE=2]strDigi = [/SIZE][SIZE=2][COLOR=#800000]"digi."[/COLOR][/SIZE][SIZE=2] & strCID & [/SIZE][SIZE=2][COLOR=#800000]".af.com"
[/COLOR][/SIZE][SIZE=2][/SIZE][SIZE=2][COLOR=#008000]'Process.Start("cmd", "/c title Pinging " & strRouter & " &&ping " & strRouter & " -t")
[/COLOR][/SIZE][SIZE=2][/SIZE][SIZE=2][COLOR=#008000]'Process.Start("cmd", "/c title Pinging " & strDigi & " &&ping " & strDigi & " -t")
[/COLOR][/SIZE][SIZE=2][/SIZE][SIZE=2][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=2].TextBox1.Text = GetProcessText([/SIZE][SIZE=2][COLOR=#800000]"ping"[/COLOR][/SIZE][SIZE=2], [/SIZE][SIZE=2][COLOR=#800000]"router."[/COLOR][/SIZE][SIZE=2] & strCID & [/SIZE][SIZE=2][COLOR=#800000]".af.com"[/COLOR][/SIZE][SIZE=2], [/SIZE][SIZE=2][COLOR=#800000]"c:\windows\system32"[/COLOR][/SIZE][SIZE=2])
[/SIZE][SIZE=2][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=2].txtCenterID.SelectAll()
[/SIZE][SIZE=2][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=2].txtCenterID.Focus()
[/SIZE][SIZE=2][COLOR=#0000ff]End[/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff]Sub
[/COLOR][/SIZE][SIZE=2][/SIZE][SIZE=2][COLOR=#0000ff]Shared[/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff]Function[/COLOR][/SIZE][SIZE=2] GetProcessText([/SIZE][SIZE=2][COLOR=#0000ff]ByVal[/COLOR][/SIZE][SIZE=2] process [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff]String[/COLOR][/SIZE][SIZE=2], [/SIZE][SIZE=2][COLOR=#0000ff]ByVal[/COLOR][/SIZE][SIZE=2] param [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff]String[/COLOR][/SIZE][SIZE=2], [/SIZE][SIZE=2][COLOR=#0000ff]ByVal[/COLOR][/SIZE][SIZE=2] workingDir [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff]String[/COLOR][/SIZE][SIZE=2]) [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff]String
[/COLOR][/SIZE][SIZE=2][/SIZE][SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] p [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] Process = [/SIZE][SIZE=2][COLOR=#0000ff]New[/COLOR][/SIZE][SIZE=2] Process [/SIZE][SIZE=2][COLOR=#008000]'This is the name of the process we want to execute 
[/COLOR][/SIZE][SIZE=2]p.StartInfo.FileName = process
[/SIZE][SIZE=2][COLOR=#0000ff]If[/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff]Not[/COLOR][/SIZE][SIZE=2] (workingDir = [/SIZE][SIZE=2][COLOR=#800000]""[/COLOR][/SIZE][SIZE=2]) [/SIZE][SIZE=2][COLOR=#0000ff]Then
[/COLOR][/SIZE][SIZE=2]p.StartInfo.WorkingDirectory = workingDir
[/SIZE][SIZE=2][COLOR=#0000ff]End[/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff]If
[/COLOR][/SIZE][SIZE=2]p.StartInfo.Arguments = param
p.StartInfo.UseShellExecute = [/SIZE][SIZE=2][COLOR=#0000ff]False[/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#008000]'need to set this to false to redirect output
[/COLOR][/SIZE][SIZE=2]p.StartInfo.RedirectStandardOutput = [/SIZE][SIZE=2][COLOR=#0000ff]True
[/COLOR][/SIZE][SIZE=2]p.Start() [/SIZE][SIZE=2][COLOR=#008000]' start the process 
[/COLOR][/SIZE][SIZE=2][/SIZE][SIZE=2][COLOR=#008000]' read all the output
[/COLOR][/SIZE][SIZE=2][/SIZE][SIZE=2][COLOR=#008000]' here we could just read line by line and display it
[/COLOR][/SIZE][SIZE=2][/SIZE][SIZE=2][COLOR=#008000]' in an output window 
[/COLOR][/SIZE][SIZE=2][/SIZE][SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][SIZE=2] output [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff]String[/COLOR][/SIZE][SIZE=2] = p.StandardOutput.ReadToEnd
[/SIZE][SIZE=2][COLOR=#008000]' wait for the process to terminate 
[/COLOR][/SIZE][SIZE=2]p.WaitForExit()
[/SIZE][SIZE=2][COLOR=#0000ff]Return[/COLOR][/SIZE][SIZE=2] output
[/SIZE][SIZE=2][COLOR=#0000ff]End[/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff]Function
End[/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff]Class
[/COLOR][/SIZE]
 
Last edited:
I changed it to a sub method and read line by line directly into the textbox.
Also hide the command window with CreateNoWindow.
VB.NET:
Private Sub GetProcessText(ByVal process As String, ByVal param As String, ByVal workingDir As String)
  Dim p As Process = New Process 'This is the name of the process we want to execute 
  p.StartInfo.FileName = process
  If Not (workingDir = "") Then
    p.StartInfo.WorkingDirectory = workingDir
  End If
  p.StartInfo.Arguments = param
  p.StartInfo.UseShellExecute = False 'need to set this to false to redirect output
  p.StartInfo.RedirectStandardOutput = True
  p.StartInfo.CreateNoWindow = True
  p.Start()
  ' read all the output
  Dim SROutput As System.IO.StreamReader = p.StandardOutput
  Dim tmp As String
  Do While p.HasExited = False
    tmp = SROutput.ReadLine
    If tmp <> "" Then
      Me.TextBox1.AppendText(tmp & vbNewLine)
    End If
  Loop
  p.Dispose()
End Sub
 
How would I execute the sub routine?

I know how to call the function but how would I use the sub routine that you created? I like what you've done with the "CreateNoWindow" and can't wait to see input come in line for line, but I don't know how to pump my variables into the Params of the sub routine and execute it.

Can you help me with this please?
 
you must be kidding...
 
Ok, the very basic stuff should be read in a beginners tutorial/book, it shouldn't take anyone more than a couple of hours reading to get tha basics of programming and VB style in particular. By now you know there is sub methods and function methods, the latter returns something, the first is just a method that does something and returns nothing. The input of a method you put into the parameters you set up to suit your needs.
So instead of running the function (with input) and catching the return like:
VB.NET:
Me.TextBox1.Text = GetProcessText("ping", "router." & strCID & ".af.com", "c:\windows\system32")
you just call the sub method (with input) like:
VB.NET:
GetProcessText("ping", "router." & strCID & ".af.com", "c:\windows\system32")
Inside that sub I used "TextBox1.Text =" to catch the line-by-line returns directly.
 
Back
Top