There are better ways to check if a file exists, but perhaps you're just using it for testing.
If one needs to update a property for a Button during cross-threaded operations, one can do either of the following:
Option 1: (Action)
Button1.Invoke(New Action(Sub()
Button1.Enabled = True
End Sub))
Option 2: (MethodInvoker)
Button1.Invoke(New MethodInvoker(Sub()
Button1.Enabled = True
End Sub))
The code below shows how to use System.Diagnostics.Process
. I've included two different ways of determining whether or not the command being run by Process
completed successfully or not.
- Using an event named ProcessCompleted. The value of
hasSuccessfullyCompleted
lets one know if the the operation successfully completed without errors.
- Using a return value from the Function. If the return value is "Success", then the operation successfully completed without errors. If an error occurred, the error message is returned.
Create a WinForms project
VS 2017:
- Open Visual Studio
- Click File
- Select New
- Select Project
- Expand Installed
- Expand Visual Basic
- Click Windows Desktop
- Select Windows Forms App (.NET Framework)
- Specify project name (name: ReadSerialPort)
- Click OK
VS 2019:
- Open Visual Studio
- Click Continue without code
- Click File
- Select New
- Select Project
- Visual Basic Windows Desktop
- Click Windows Forms App (.NET Framework)
- Click Next
- Specify project name (name: ReadSerialPort)
- Click Create
Note: From this point forward, the process is the same for both VS 2017 and VS 2019.
Create a class (name: HelperProcess.vb)
- In VS menu, click Project
- Select Add Class
- For name, enter "HelperProcess.vb"
- Click Add
HelperProcess.vb
Public Class HelperProcess
Public Event ErrorDataReceived(sender As Object, data As String)
Public Event OutputDataReceived(sender As Object, data As String)
Public Event ProcessCompleted(sender As Object, hasSuccessfullyCompleted As Boolean)
Private ProcessError As String = String.Empty
Public Function RunCmd(ByVal exePath As String, ByVal Optional arguments As String = Nothing) As String
Dim errMsg As String = String.Empty
'set value
ProcessError = String.Empty
If String.IsNullOrEmpty(exePath) Then
errMsg = "exePath not specified"
Debug.WriteLine(errMsg)
're-initialize
ProcessError = "Error: " & errMsg
Throw New Exception(errMsg)
End If
Try
'create new instance
Dim psInfo As ProcessStartInfo = New ProcessStartInfo(exePath, arguments)
'set properties
psInfo.Arguments = arguments 'arguments
psInfo.CreateNoWindow = True 'don't create a window
psInfo.RedirectStandardError = True 'redirect standard Error
psInfo.RedirectStandardOutput = True 'redirect standard output
psInfo.RedirectStandardInput = False
psInfo.UseShellExecute = False 'If True, uses 'ShellExecute'; if false, uses 'CreateProcess'
psInfo.WindowStyle = ProcessWindowStyle.Hidden
psInfo.ErrorDialog = False
'create new instance - setting the desired properties
Using p As Process = New Process() With {.EnableRaisingEvents = True, .StartInfo = psInfo}
'subscribe to events (add event handlers)
AddHandler p.ErrorDataReceived, AddressOf Process_ErrorDataReceived
AddHandler p.OutputDataReceived, AddressOf Process_OutputDataReceived
'start process
p.Start()
p.BeginErrorReadLine() 'begin async reading for standard error
p.BeginOutputReadLine() 'begin async reading for standard output
'waits until the process is finished before continuing
p.WaitForExit()
'unsubscribe from events (remove event handlers)
RemoveHandler p.ErrorDataReceived, AddressOf Process_ErrorDataReceived
RemoveHandler p.OutputDataReceived, AddressOf Process_OutputDataReceived
End Using
Catch ex As System.ComponentModel.Win32Exception
errMsg = "Error (Win32Exception): " & ex.Message
Debug.WriteLine(errMsg)
'set value
ProcessError = errMsg
Throw ex
Catch ex As Exception
errMsg = "Error: " & ex.Message
Debug.WriteLine(errMsg)
'set value
ProcessError = errMsg
Throw ex
End Try
If Not String.IsNullOrEmpty(ProcessError) Then
'raise event
RaiseEvent ProcessCompleted(Me, False)
Return "Error: " & ProcessError
Else
'raise event
RaiseEvent ProcessCompleted(Me, True)
End If
Return "Success"
End Function
Private Sub Process_ErrorDataReceived(sender As Object, e As DataReceivedEventArgs)
'ToDo: add desired code
If Not String.IsNullOrEmpty(e.Data) Then
Debug.WriteLine("Process_ErrorDataReceived: " & e.Data)
If Not String.IsNullOrEmpty(ProcessError) Then
'add space
ProcessError += " "
End If
'append
ProcessError += e.Data
'raise event
RaiseEvent ErrorDataReceived(Me, e.Data)
End If
End Sub
Private Sub Process_OutputDataReceived(sender As Object, e As DataReceivedEventArgs)
'ToDo: add desired code
If Not String.IsNullOrEmpty(e.Data) Then
Debug.WriteLine("Process_OutputDataReceived: " & e.Data)
'raise event
RaiseEvent OutputDataReceived(Me, e.Data)
End If
End Sub
End Class
Open Properties Window
- In VS menu, select View
- Select Properties Window
Open Solution Explorer
- In VS menu, select View
- Select Solution Explorer
- In Solution Explorer, double-click Form1.vb to open the designer.
Add Buttons to Form1

Add "Run" button to Form1
- In VS menu, select View
- Select Toolbox
- Select Button
- Click on Form1 to add the button to the form
- In Properties Window, for "button1", set (name): btnRun; set Text: Connect
- In Properties Window, click
(Events). Double-click Click to add event handler to Form1.vb
Add "Button1" button to Form1
- In VS menu, select View
- Select Toolbox
- Select Button
- Click on Form1 to add the button to the form
Add "Load" event handler to Form1
- In Properties Window, for "Form1"", click
(Events). Double-click Load to add event handler to Form1.vb
Modify Form1.vb code
- In Solution Explorer, right-click Form1.vb
- Select View Code
Form1.vb
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'set value
Button1.Enabled = False
End Sub
Private Sub btnRun_Click(sender As Object, e As EventArgs) Handles btnRun.Click
'set value
Button1.Enabled = False
Dim helper As New HelperProcess
'subscribe to events (add event handlers)
AddHandler helper.ErrorDataReceived, AddressOf Helper_ErrorDataReceived
AddHandler helper.OutputDataReceived, AddressOf Helper_OutputDataReceived
AddHandler helper.ProcessCompleted, AddressOf Helper_ProcessCompleted
'set value
Dim folderName As String = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
Dim filename As String = System.IO.Path.Combine(folderName, "element.docx")
Dim arguments As String = String.Format("/c dir ""{0}"" | find /v ""Volume"" | find /v ""Directory of"" | find /v ""bytes"" ", filename)
'execute
Dim result As String = helper.RunCmd("cmd", arguments)
'unsubscribe from events (remove event handlers)
RemoveHandler helper.ErrorDataReceived, AddressOf Helper_ErrorDataReceived
RemoveHandler helper.OutputDataReceived, AddressOf Helper_OutputDataReceived
RemoveHandler helper.ProcessCompleted, AddressOf Helper_ProcessCompleted
'set value
helper = Nothing
Debug.WriteLine("result: " & result)
If result = "Success" Then
Button1.Enabled = True
Else
Button1.Enabled = False
End If
End Sub
Private Sub Helper_ErrorDataReceived(sender As Object, data As String)
'ToDo: add desired code
If Not String.IsNullOrEmpty(data) Then
Debug.WriteLine("Helper_ErrorDataReceived: " & data)
End If
End Sub
Private Sub Helper_OutputDataReceived(sender As Object, data As String)
'ToDo: add desired code
If Not String.IsNullOrEmpty(data) Then
Debug.WriteLine("Helper_OutputDataReceived: " & data)
End If
End Sub
Private Sub Helper_ProcessCompleted(sender As Object, hasSuccessfullyCompleted As Boolean)
'ToDo: add desired code and/or uncomment desired code below
Debug.WriteLine("hasSuccessFullyCompleted: " & hasSuccessfullyCompleted.ToString())
If hasSuccessfullyCompleted Then
'Button1.Invoke(New MethodInvoker(Sub()
'Button1.Enabled = True
'End Sub))
'Button1.Invoke(New Action(Sub()
'Button1.Enabled = True
'End Sub))
Else
'Button1.Invoke(New MethodInvoker(Sub()
'Button1.Enabled = False
'End Sub))
'Button1.Invoke(New Action(Sub()
'Button1.Enabled = False
'End Sub))
End If
End Sub
End Class