I was writing some code to start and stop a VPN connection for a Visual Basic application that I was writing. I am normally a straight VB/data guy and I don't do much with process and threading. Almost all the examples I found online were written for C or C++. Did my best to convert the code over to VB.

I watched processes on the test workstation and things appear to be closing out but I am not convinced I wrote everything correctly or according to Best Practices. Would appreciate any time and advice on the code below. Did I terminate processes correctly? Follow norms? etc?

I put bogus information is VPN fields for obvious reasons.

Oh, one annoying thing. When I click to disconnect VPN, my first line goes in OK. A message from the process goes in and says Disconnecting...
I will not display disconnected. When I try to add this line
Code:
            txtMsg.AppendText(String.Concat("-- ", "Disconnected", Environment.NewLine))
at the bottom of the sub, the line appears before "Disconnecting" instead of the bottom. Assuming it hits the command before the process officially ends. Is pause necessary here and something else? I kept reading that "waitforexit" shouldn't be used for the realtime writing of messages and when invoked; the message won't got to the form. Wondering what another possibility might be to get that last line?

Code from Form:
Code:
    Private Sub ConnNE_Click(sender As Object, e As EventArgs) Handles ConnNE.Click
        Dim p As Process = New Process
        Dim pi As ProcessStartInfo = New ProcessStartInfo()

        txtMsg.Clear()

        With pi
            .WorkingDirectory = "c:\Program Files (x86)\SonicWALL\SSL-VPN\NetExtender\"
            .FileName = "cmd.exe"
            .Arguments = "/c NECLI.exe connect -s myserver.com -d myDomain.local -u myID -p myPassword"
            .WindowStyle = ProcessWindowStyle.Normal
            .CreateNoWindow = True
            .UseShellExecute = False
            .RedirectStandardOutput = True
            .RedirectStandardError = True
        End With

        p.StartInfo = pi

        Try
            AddHandler p.OutputDataReceived, AddressOf consoleOutputHandler
            AddHandler p.ErrorDataReceived, AddressOf consoleErrorHandler

            txtMsg.AppendText(String.Concat("-- ", "Initializing Connection", Environment.NewLine))

            p.Start()
            p.BeginOutputReadLine()
            'p.WaitForExit()
            p.Close()

        Catch ex As Exception
            MsgBox(ex.Message)
        End Try

    End Sub

    Private Delegate Sub consoleOutputDelegate(ByVal outputString As String)

    Private Sub consoleOutput(ByVal outputString As String)
 
        If Me.InvokeRequired Then
            Dim del As New consoleOutputDelegate(AddressOf consoleOutput)
            Dim args As Object() = {outputString}
            Me.Invoke(del, args)
        Else
            txtMsg.AppendText(String.Concat("-- ", outputString, Environment.NewLine))
            'txtMsg.Refresh()
        End If
    End Sub

    Sub consoleOutputHandler(ByVal sendingProcess As Object, ByVal outLine As DataReceivedEventArgs)
        If Not String.IsNullOrEmpty(outLine.Data) Then
            consoleOutput(outLine.Data)
        End If
    End Sub

    Private Delegate Sub consoleErrorDelegate(ByVal errorString As String)
 
   Private Sub consoleError(ByVal errorString As String)
         If Me.InvokeRequired Then
            Dim del As New consoleErrorDelegate(AddressOf consoleError)
            Dim args As Object() = {errorString}
            Me.Invoke(del, args)
        Else
                        txtMsg.AppendText(String.Concat("Error: ", errorString, Environment.NewLine))
        End If
    End Sub
  
    Private Sub consoleErrorHandler(ByVal sendingProcess As Object, ByVal errLine As DataReceivedEventArgs)
        If Not String.IsNullOrEmpty(errLine.Data) Then
                        consoleError(errLine.Data)
        End If
    End Sub

    Private Sub DisConnNE_Click(sender As Object, e As EventArgs) Handles DisConnNE.Click
        Dim p As Process = New Process
        Dim pi As ProcessStartInfo = New ProcessStartInfo()

        With pi
            .WorkingDirectory = "c:\Program Files (x86)\SonicWALL\SSL-VPN\NetExtender\"
            .FileName = "cmd.exe"
            .Arguments = "/c NECLI.exe disconnect"
            .WindowStyle = ProcessWindowStyle.Normal
            .CreateNoWindow = True
            .UseShellExecute = False
            .RedirectStandardOutput = True
            .RedirectStandardError = True
        End With

        p.StartInfo = pi

        Try
            AddHandler p.OutputDataReceived, AddressOf consoleOutputHandler
            AddHandler p.ErrorDataReceived, AddressOf consoleErrorHandler

            txtMsg.AppendText(String.Concat("-- ", "Initializing Disconnect", Environment.NewLine))
            'txtMsg.Refresh()

            p.Start()
            p.BeginOutputReadLine()
            'p.WaitForExit()
            p.Close()

        Catch ex As Exception
            MsgBox(ex.Message)
        End Try

    End Sub