System.Diagnostic.Process - inheritance problem

MRTrevorF

New member
Joined
Aug 20, 2008
Messages
2
Programming Experience
3-5
I've been coding in .NET for several years now. I can usually figure things out on my own or by Googling my woes away, but this one has me stumped.

Here's the deal:

I'm writing a program, to spawn off a number of Processes and watch for the Process.Exited event. When the Process has actually exited, I need to prompt the User with a Form they need to fill out.

In order to get the parameters I need, I use System.Diagnostics.ProcessStartInfo.

VB.NET:
    Private Sub PlayMovie(ByVal appPath As String, ByVal li As classListViewItem)

        Dim movPath As String = MyCase.CasePath & li.SubItems(2).tag

        ' Build a Process for this player and movie
        Dim psInfo As New System.Diagnostics.ProcessStartInfo(appPath, ControlChars.Quote & movPath & ControlChars.Quote)
        psInfo.WindowStyle = ProcessWindowStyle.Normal

        ' Create a process and associate all the data we need for categorization later on
        Dim myProcess As New Process
        myProcess = System.Diagnostics.Process.Start(psInfo)

        ' Add an event handler to watch for the Process when it ends
        AddHandler myProcess.Exited, AddressOf Me.ProcessExited

    End Sub

BUT when the Process.Exited event actually fired, it came back as a separate thread. In order to get the User's Feedback, I have to spawn a new Window and populate it with information about the movie. All of that information is stored inside variables, classes, and controls on the Main Form.

Because of the dreaded Cross-Threading errors, I can't gain access to that information in the Process.Exited event...

So I tried to create a custom Process class, and pass in all the data I needed to know about the file:

VB.NET:
Public Class classProcess

    Inherits System.Diagnostics.Process

    Dim _myCase As classCase
    Dim _myFilter As classFilter
    Dim _myRecord As classRecord

    Public Property MyCase() As classCase
        Get
            Return _myCase
        End Get
        Set(ByVal value As classCase)
            _myCase = value
        End Set
    End Property

    Public Property MyFilter() As classFilter
        Get
            Return _myFilter
        End Get
        Set(ByVal value As classFilter)
            _myFilter = value
        End Set
    End Property

    Public Property MyRecord() As classRecord
        Get
            Return _myRecord
        End Get
        Set(ByVal value As classRecord)
            _myRecord = value
        End Set
    End Property

End Class


In theory my brilliance should have been well rewarded...but it wasn't. Here's the altered code:

VB.NET:
    Private Sub PlayMovie(ByVal appPath As String, ByVal li As classListViewItem)

        Dim movPath As String = MyCase.CasePath & li.SubItems(2).tag

        ' Build a Process for this player and movie
        Dim psInfo As New System.Diagnostics.ProcessStartInfo(appPath, ControlChars.Quote & movPath & ControlChars.Quote)
        psInfo.WindowStyle = ProcessWindowStyle.Normal

        ' Create a process and associate all the data we need for categorization later on
        Dim myProcess As New classProcess
        myProcess = System.Diagnostics.Process.Start(psInfo)
        myProcess.MyRecord = li.MyRecord
        myProcess.MyCase = MyCase
        myProcess.MyFilter = MyFilter
        myProcess.EnableRaisingEvents = True

        ' Add an event handler to watch for the Process when it ends
        AddHandler myProcess.Exited, AddressOf Me.ProcessExited

    End Sub

This code, while it compiles fine, won't survive Runtime. I get an error at the "myProcess = System.Diagnostics.Process.Start(psInfo)" line.

The error states that the program was unable to "Case type of System.Diagnostics.Process to classProcess"

When I looked a bit closer, it is true that the .Start() method does indeed return a System.Diagnostics.Process object.

I tried to create my own custom object of the ProcessStartInfo class, but unfortunately, that class has been marked as "Un-inheritable"...

I also tried to create a separate class, that didn't Inherit from System.Diagnostics.Process, but instead has a Process object contained within. I had hoped that when the Process.Exited event would fire, I would be able to gain access to the Parent object, but guess what, there isn't a Parent property exposed in the Process class...

That's the limits of my imagination on the subject. I'm stuck, and am wondering if anyone has any brighter ideas than mine :p

Thanks to anyone in advance.
 
Cross-Threading errors is not a dread, it is just a multithreading beginner problem you have to learnt how to handle. It is not difficult, just learn multithreading and exercise and you will get it in no time.

If your thoughts about what is supposed to happen from Exited event includes depending on the info inputted to the process you started then you are better off not making this separation, it just raises other management problems. Instead use a BackGroundWorker where in DoWork event you run the process and WaitForExit, then use the "UI-safe" progress/completed events to finish off against UI.
 
Thanks, John. That was the right pointer I needed. I've never really worked with Processes before, but a combination of that and the BackgroundWorker did the trick.
 
Back
Top