The name of the actual class (ThreadWatcher) is misleading, sorry about that.

Currently, the class will accept either a file to launch/monitor or a process to attach to. The whole purpose of the monitor is to allow you to hook onto a process and watch it and restart it if it ends.

Currently, it does not get any text back (if it's a console application) because there's no handles for it but it's on the ToDo list.

Enough of me yammering, Here's the code:

vb.net Code:
  1. Public Class ThreadWatcher
  2.     'Variables
  3.     Private WithEvents m_Thread As Process
  4.     Private Executable As String = String.Empty
  5.     Private Running As Boolean = False
  6.  
  7.     'Events
  8.     Public Event Terminated()
  9.     Public Event ThreadError(ByVal errorMsg As String)
  10.     ''' <summary>
  11.     ''' Create a new instance of the class.
  12.     ''' </summary>
  13.     ''' <param name="filename">The file to launch.</param>
  14.     ''' <remarks></remarks>
  15.     Public Sub New(ByVal filename As String)
  16.         Executable = filename
  17.     End Sub
  18.  
  19.     ''' <summary>
  20.     ''' Create a new instance of the class. You don't need to call Start() here!
  21.     ''' </summary>
  22.     ''' <param name="process">The process to monitor.</param>
  23.     ''' <remarks></remarks>
  24.     Public Sub New(ByVal process As Process)
  25.         Executable = String.Empty
  26.         m_Thread = process
  27.         m_Thread.EnableRaisingEvents = True
  28.         Executable = m_Thread.MainModule.FileName ' :D
  29.         Running = True
  30.     End Sub
  31.  
  32.     ''' <summary>
  33.     ''' Start the Process.
  34.     ''' </summary>
  35.     ''' <remarks></remarks>
  36.     Public Sub Start()
  37.         If Running = True Then RaiseEvent ThreadError("This Thread Watcher is already in use: " & m_Thread.MainWindowTitle) : Exit Sub
  38.         If Executable <> String.Empty Then m_Thread = New Process With {.StartInfo = New ProcessStartInfo(Executable), .EnableRaisingEvents = True}
  39.         If IO.File.Exists(Executable) Then m_Thread.Start() Else RaiseEvent ThreadError("The file does not exist!") : Exit Sub
  40.         Running = True
  41.     End Sub
  42.  
  43.     ''' <summary>
  44.     ''' Restart the Process.
  45.     ''' </summary>
  46.     ''' <remarks></remarks>
  47.     Public Sub Restart()
  48.         Call Start()
  49.     End Sub
  50.  
  51.     ''' <summary>
  52.     ''' Stop the Process.
  53.     ''' </summary>
  54.     ''' <remarks></remarks>
  55.     Public Sub StopProcess()
  56.         Try
  57.             m_Thread.Kill()
  58.         Catch ex As Exception
  59.             RaiseEvent ThreadError(ex.Message.ToString)
  60.         End Try
  61.     End Sub
  62.     Private Sub m_Thread_Exited(ByVal sender As Object, ByVal e As System.EventArgs) Handles m_Thread.Exited
  63.         Running = False
  64.         RaiseEvent Terminated()
  65.     End Sub
  66.  
  67.     ''' <summary>
  68.     ''' Returns a True or False if the process is active or not.
  69.     ''' </summary>
  70.     ''' <returns></returns>
  71.     ''' <remarks></remarks>
  72.     Public Function Active() As Boolean
  73.         Return Running
  74.     End Function
  75.  
  76.     ''' <summary>
  77.     ''' Dispose of the class. Probably could be managed better, but whatever....
  78.     ''' </summary>
  79.     ''' <remarks></remarks>
  80.     Public Sub Dispose()
  81.         m_Thread.Close()
  82.         m_Thread.Dispose()
  83.         Me.Finalize()
  84.     End Sub
  85. End Class

Questions, comments, and criticism are welcome. The code is available for all to use, and credit isn't required but welcome.