3

I'm calling a COM object from a Word-Addin.

After one point, I want to close my COM object and return to Word. My Problem is, that my COM object (my Import form of another application) keeps being opened. When I try to close it manually I get following error:

https://i.stack.imgur.com/xdvGt.png

My Code:

   Private Sub save_Click(sender As Object, e As RibbonControlEventArgs) Handles save.Click
    Dim importer = GetObject("", "IMPORT.Application")
    Dim dictionary As Dictionary(Of Integer, String)
    Dim doc As Document = Globals.ThisAddIn.Application.ActiveDocument
    Try
        'Doing some stuff...

        importer.SetWindowVisible(False)
        doc.Close(False)

    Catch ex As Exception
        MessageBox.Show(ex.message)
    Finally
        GC.Collect()
        GC.WaitForPendingFinalizers()
        System.Runtime.InteropServices.Marshal.ReleaseComObject(importer)
        importer = Nothing
    End Try
End Sub

They explain everywhere on the web, that I have to use following command to release the COM object:

System.Runtime.InteropServices.Marshal.ReleaseComObject(importer)

It doesn't seem to work in my case. Does anybody know why?

Is it possible to get the processID of my COM Application, in order to kill it, in the end of my code?

// EDIT

So I tried calling myOtherMethod() in the finally statement (importer is a class variable now). I'm not doing anything else. Nothing has changed.

Private Sub myOtherMethod()
    GC.WaitForPendingFinalizers()
    System.Runtime.InteropServices.Marshal.ReleaseComObject(importer)
End Sub
manuell
  • 7,528
  • 5
  • 31
  • 58
user2871190
  • 241
  • 2
  • 5
  • 19
  • 1
    The jitter optimizer can get rid of the importer = Nothing statement. But can't do anything about the ReleaseComObject() call. So GC.Collect() can't do its job. Delete those two statements. Move the rest of the code in another method so it can still work when you debug. – Hans Passant Mar 06 '19 at 10:12
  • 1
    Do you know which line is causing the error message to be displayed? Also, Have you tried running the `GC` commands AFTER the `ReleaseComObject` line? – JayV Mar 06 '19 at 10:12
  • @HansPassant Thanks for your help! I removed the two lines, but it didn't change anything. – user2871190 Mar 06 '19 at 10:22
  • @JayV Also thank you for your help! Chaning the lines didn't change anything ether. The error appears if I want to close Word, or my Importer, because the reference is not released properly. – user2871190 Mar 06 '19 at 10:28
  • @HansPassant did I do it correctly? Look at the // EDIT part of my post. Or did I get you wrong? – user2871190 Mar 06 '19 at 17:13
  • For an example of the pattern Hans described see [this post](https://stackoverflow.com/a/36578663/2592875). The example is for releasing Excel, but the pattern is applicable for all COM interop. Do not retain any of the `ReleaseComObject` calls . Also keep all variables that reference COM objects local to the work method. – TnTinMn Jun 01 '19 at 03:12
  • Close but no cigar. You need to move the code inside the save_Click() method into another method. Call it in save_Click, add GC.Collect() there. Just like the last snippet in [this post](https://stackoverflow.com/a/25135685/17034). – Hans Passant Jun 01 '19 at 12:54

2 Answers2

0

You have COM object leak. Smart pointer to the COM object stored and not released somewhere in your code. You should release all instances of the pointer.

Tania Chistyakova
  • 3,928
  • 6
  • 13
0

You start your IMPORT.Application, you use it, but you never terminate it. Your IMPORT.Application should have a method that can be called to terminate it. Then, the following calls in your add-in will properly release it.

' Quit instance.
importer.Quit()
System.Runtime.InteropServices.Marshal.ReleaseComObject(importer)
importer = Nothing
' Could be useful to uncomment these lines for debugging purpose. You would be able
' to see whether the importer instance is released when GC runs.
' In production code, never call the Garbage Collector though.
'System.Threading.Thread.Sleep(50)
'System.GC.Collect()
'System.GC.WaitForPendingFinalizers()
RobertBaron
  • 2,817
  • 1
  • 12
  • 19