CMD output to form

Here's some code I got from elsewhere:
VB.NET:
'Form code from sample project

Private Results As String
Private Delegate Sub delUpdate()
Private Finished As New delUpdate(AddressOf UpdateText)

Private Sub UpdateText()
    txtResults.Text = Results
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Dim CMDThread As New Threading.Thread(AddressOf CMDAutomate)
    
    CMDThread.Start()
End Sub

Private Sub CMDAutomate()
    Dim myprocess As New Process
    Dim StartInfo As New System.Diagnostics.ProcessStartInfo
    
    StartInfo.FileName = "cmd" 'starts cmd window
    StartInfo.RedirectStandardInput = True
    StartInfo.RedirectStandardOutput = True
    StartInfo.UseShellExecute = False 'required to redirect
    StartInfo.CreateNoWindow = True 'creates no cmd window
    
    myprocess.StartInfo = StartInfo
    myprocess.Start()
    
    Dim SR As System.IO.StreamReader = myprocess.StandardOutput
    Dim SW As System.IO.StreamWriter = myprocess.StandardInput
    
    SW.WriteLine(txtCommand.Text) 'the command you wish to run.....
    SW.WriteLine("exit") 'exits command prompt window
    
    Results = SR.ReadToEnd 'returns results of the command window
    
    SW.Close()
    SR.Close()
    
    'invokes Finished delegate, which updates textbox with the results text
    Invoke(Finished)
End Sub
 
Here's some code I got from elsewhere:
VB.NET:
'Form code from sample project

Private Results As String
Private Delegate Sub delUpdate()
Private Finished As New delUpdate(AddressOf UpdateText)

Private Sub UpdateText()
    txtResults.Text = Results
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Dim CMDThread As New Threading.Thread(AddressOf CMDAutomate)
  
    CMDThread.Start()
End Sub

Private Sub CMDAutomate()
    Dim myprocess As New Process
    Dim StartInfo As New System.Diagnostics.ProcessStartInfo
  
    StartInfo.FileName = "cmd" 'starts cmd window
    StartInfo.RedirectStandardInput = True
    StartInfo.RedirectStandardOutput = True
    StartInfo.UseShellExecute = False 'required to redirect
    StartInfo.CreateNoWindow = True 'creates no cmd window
  
    myprocess.StartInfo = StartInfo
    myprocess.Start()
  
    Dim SR As System.IO.StreamReader = myprocess.StandardOutput
    Dim SW As System.IO.StreamWriter = myprocess.StandardInput
  
    SW.WriteLine(txtCommand.Text) 'the command you wish to run.....
    SW.WriteLine("exit") 'exits command prompt window
  
    Results = SR.ReadToEnd 'returns results of the command window
  
    SW.Close()
    SR.Close()
  
    'invokes Finished delegate, which updates textbox with the results text
    Invoke(Finished)
End Sub

THis is great! Thanks bro!
I actually have like this code but not complete like yours
Now it's working :)
 
The output you're reading is whatever is displayed in the command window. If you don't want that in the output then you'd have to force the command window not to display it. I don't know if that's possible or how you'd do it but that's not a VB issue specifically.

If you can't force the command window not to include the current directory prompt then the alternative is to remove it after reading the output. When you read output from the process, you get it as a String. You can then manipulate it like any other String. before displaying it in your own form. You could call String.Replace to replace all instances of the folder path with an alternative if you read the output as a single block. If you read line by line then you could call String.StartsWith to detect the folder path prompt and call Substring to get only what comes after, then add a different prefix if you want. It's just string manipulation, like any other.
 
It may be better to use the Process.OutputDataReceived Event (System.Diagnostics)
Quick example:
VB.NET:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Task.Run(Sub() CMDAutomate())
End Sub

Private Sub CMDAutomate()
    proc = New Process
    With proc.StartInfo
        .FileName = "cmd" 'starts cmd window
        .Arguments = "/c " & txtCommand.Text
        .RedirectStandardOutput = True
        .UseShellExecute = False 'required to redirect
        .CreateNoWindow = True 'creates no cmd window
    End With
    With proc
        .EnableRaisingEvents = True
        .Start()
        .BeginOutputReadLine()
        .WaitForExit()
        .Dispose()
    End With
End Sub

Private WithEvents proc As Process

Private Sub proc_OutputDataReceived(sender As Object, e As DataReceivedEventArgs) Handles proc.OutputDataReceived
    Invoke(Sub() txtResults.AppendText(e.Data & vbNewLine))
End Sub
No input lines here. Added benefit, you get to see each output line as it is received.
 
There is an alternative if you want to mimic the CMD applet window using the Ping Class (System.Net.NetworkInformation), but it requires a lot of tweaking. The code is below, but it requires some customising, but I've given you a starter. This is also UI friendly and uses threading and delegating. Currently, its not as good as @JohnH's answer, since I haven't time to finish it for you. However, maybe you'll find some use for it :
VB.NET:
Option Strict On
Imports System.Management
Imports System.Net.NetworkInformation
Imports System.Threading

Public Class Form1

    Public Delegate Sub Callback(ByVal s As String)

    Private Sub UpdateUI(ByVal this_Result As String)
        RichTextBox1.Text = RichTextBox1.Text + String.Concat(this_Result, Environment.NewLine)
    End Sub
    Private Sub PingThis(ByVal p_Timeout As Integer, ByVal packet_Size As Byte(), ByVal IPA As String)
        Using ping As New Ping()
            If ping.Send(IPA, p_Timeout, packet_Size).Status = IPStatus.Success Then
                Dim result = New String() {
                    $"Microsoft Windows [{GetVersion()}] (c) {Date.Today.Year} Microsoft Corporation. All rights reserved.",
                    $"{Environment.NewLine} => Ping [{IPA}] {Environment.NewLine}",
                    $"Pinging {IPA} [{ping.Send(IPA, p_Timeout, packet_Size).Address}] with {packet_Size(0).ToString} bytes of data:",
                    String.Concat("IP4V Address", ": ", IPA),
                    String.Format("Pinged : {0}", ping.Send(IPA, p_Timeout, packet_Size).Address),
                    String.Format("Time for round trip : {0}", ping.Send(IPA, p_Timeout, packet_Size).RoundtripTime),
                    String.Format("TTL was : {0}", ping.Send(IPA, p_Timeout, packet_Size).Options.Ttl),
                    String.Format("Data Buffer : {0}", ping.Send(IPA, p_Timeout, packet_Size).Buffer.Length)
                }
                For Each str As String In result
                    RichTextBox1.Invoke(New Callback(AddressOf UpdateUI), str)
                Next
            End If
        End Using
    End Sub
    Private Function GetVersion() As String
        Dim version As String = String.Empty
        Using ManagementObject_Searcher As ManagementObjectSearcher = New ManagementObjectSearcher("SELECT * FROM Win32_OperatingSystem")
            Dim Object_Collection As ManagementObjectCollection = ManagementObject_Searcher.Get()
            If Not Object_Collection Is Nothing Then
                For Each obj As ManagementObject In Object_Collection
                    version = String.Concat(obj("Caption").ToString, " ", obj("Version").ToString)
                Next
            End If
            Dim result As String = version.Remove(0, version.LastIndexOf(" ")).TrimStart
            Return result
        End Using
    End Function
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim packet_Size = New Byte() {32}
        Dim new_Ping = New Ping
        Dim thread As New Thread(Sub() PingThis(60, packet_Size, "google.co.uk"))
        thread.Start()
    End Sub
End Class
You can change the way it outputs by editing the highlighted variable.

 
Last edited:
Back
Top