Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

make sure an interop object has exited 1

Status
Not open for further replies.

misterstick

Programmer
Apr 7, 2000
633
GB
i'm using office components via COM. i call Application.Quit() at the end of processing, but the application (Access, Word, or Excel) is left running.

how can i shut it down?

how can i check to see that it's really gone?

many thanks,


mr s. <;)

 
I've found that that method has limited success and use this instead - it has never failed me:

Code:
  'Our instance of Excel
  Private ExcelProcess As Integer
  'All other instances of Excel
  Private ExcelProcesses() As Process

  Private XLApp As Excel.Application = Nothing

  Private Sub GetExcelProcessID(ByVal OurInstance As Boolean)

    'This sub is run twice, first it collects all current instances of Excel (OurInstance = False)
    'Then it identifies our instance (OurInstance = True)
    'This way we have the Process ID for our instance
    If Not OurInstance Then
      ExcelProcesses = Diagnostics.Process.GetProcessesByName("Excel")
    Else
      Dim NewExcelProcesses() As Process = Diagnostics.Process.GetProcessesByName("Excel")
      Dim found As Boolean
      For Each p As Process In NewExcelProcesses
        found = False
        For Each p1 As Process In ExcelProcesses
          If p.Id = p1.Id Then
            found = True
            Exit For
          End If
        Next
        If Not found Then
          ExcelProcess = p.Id
          Exit For
        End If
      Next
    End If

  End Sub


  Private Function StartExcel(ByVal Show As Boolean) As Boolean

    ExcelProcess = Nothing
    GetExcelProcessID(False)
    Try
      XLApp = New Excel.Application
      XLApp.Visible = Show
      GetExcelProcessID(True)
      Return True
    Catch ex As Exception
      MessageBox.Show("Unable to start Excel because: " + ex.Message)
      Return False
    End Try

  End Function

  Private Function EndExcel() As Boolean

    'Elsewhere all Excel objects have been properly closed
    'Since following the "rules" has only limited success..
    '..follow the rules ...
    Try
      Dim x As Integer = 0
      XLApp.Quit()
      x = System.Runtime.InteropServices.Marshal.FinalReleaseComObject(XLApp)
      XLApp = Nothing
      Return True
    Catch ex As Exception
      MessageBox.Show("Unable to exit Excel because: " + ex.Message)
      Return False
    Finally
      '... now guarantee that our instance is killed
      Diagnostics.Process.GetProcessById(ExcelProcess).Kill()
    End Try

  End Function

It's VB, but does nothing clever so should be easy enough to convert.


Hope this helps.

[vampire][bat]
 
the microsoft article suggests that if you make sure you dereference all objects the call to application.Quit and NAR(application) should terminate the process.

having just rejigged my code to use explicit objects rather than implicit ones (the single word vba call ActiveDocument.Paragraphs(ActiveDocument.Paragraphs.Count - 1).Range.ListFormat.ApplyListTemplate ListTemplate:=Application.ListGalleries(wdNumberGallery).ListTemplates(7), ContinuePreviousList:=False, ApplyTo:=wdListApplyToWholeList, DefaultListBehavior:=wdWord9ListBehavior
is my current favourite) and making sure i always apply System.Runtime.InteropServices.Marshal.ReleaseComObject() to every object when i'm done with it seems to have done the trick but is a real pain and oh so easy to screw up.

does the call to Diagnostics.Process.GetProcessById().Kill() free up the implied objects in the same way? it would be much more convenient (not to mention readable) not to have to split out lines like the one above, but i'd be wary of memory leakage.



mr s. <;)

 
Limited testing on memory leakage that I have done seems to suggest yes.

The main program in which I use this technique potentially creates and destroys Excel upto maybe 100 times during the course of a day and so far no one has reported any problems, but ...


Hope this helps.

[vampire][bat]
 
i love this way of doing it. one call at the end to tidy up everything is much the better way.

unfortunately, there is a flaw in your logic.

[ol]
[li]make a list of excel instances.[/li]
[li]open excel.[/li]
[li]make a second list of excel instances.[/li]
[li]the first excel instance in list2 that doesn't exist in list1 must be ours.[/li]
[/ol]

i understand that the likelihood of a second instance being opened between actions 1 and 3 is pretty small, but users get bored in a nanosecond and open applications howsoever they feel. you can't just kill the first random excel process you find.

is there a better way of telling which application we just opened? since we have a pointer to it, there must be the process id we require in memory somewhere.

many thanks,


mr s. <;)

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top