COM object that has been separated from its underlying RCW...

G

Guest

Hi,

On closing our App, we get following 'InvalidComObjectException': "COM
object that has been separated from its underlying RCW cannot be used"

The App has been upgraded from .Net1.1 to .Net2.0 a long time ago.
Recently we started using the Application Framework, combined with a Splash
Screen. About that moment we are having this issue.

I thought the problem only existed while debugging, but now ,having a
deployed version, it seems like Windows sometimes reoprts e fatal error on
Exiting our app.

Anyone some tips, because I don't know where to look anymore.



Stack:
[Managed to Native Transition]
System.Management.dll!System.Management.SinkForEventQuery.Cancel() + 0x3d bytes
System.Management.dll!System.Management.ManagementEventWatcher.Stop() +
0x55 bytes
System.Management.dll!System.Management.ManagementEventWatcher.Finalize()
+ 0x1b bytes


DisAss:
0000003d mov esi,eax
0000003f mov ecx,dword ptr [ebp-24h]
00000042 call 000000D0
00000047 test esi,esi
00000049 jge 0000008F
0000004b mov eax,esi
0000004d sar eax,1Fh
00000050 mov edx,eax
00000052 mov eax,esi
00000054 and eax,0FFFFF000h
00000059 xor edx,edx
0000005b test edx,edx
0000005d jne 0000006F
0000005f cmp eax,80041000h
00000064 jne 0000006F
00000066 mov ecx,esi
00000068 call 000892C0
0000006d jmp 0000008F
0000006f test esi,esi
00000071 jge 0000008F
00000073 mov edx,41Fh
00000078 mov ecx,1
0000007d call 12957360
00000082 mov edx,dword ptr [eax+00000A54h]
00000088 mov ecx,esi
0000008a call 12A7B09B
0000008f mov dword ptr [ebp-1Ch],0
00000096 mov dword ptr [ebp-18h],0FCh
0000009d push 6751C827h
000000a2 jmp 000000A4
000000a4 mov ecx,dword ptr [ebp-24h]
000000a7 call 12957653
000000ac pop eax
000000ad jmp eax
000000af lea esp,[ebp-0Ch]
000000b2 pop ebx
000000b3 pop esi
000000b4 pop edi
000000b5 pop ebp
000000b6 ret
000000b7 mov dword ptr [ebp-18h],0
000000be jmp 000000AF
 
R

Robinson

On closing our App, we get following 'InvalidComObjectException': "COM
object that has been separated from its underlying RCW cannot be used"



Hi,


I used to get this error often when trying to use an object that has been
garbage collected. You should make sure you explicitly dispose and RELEASE
all COM objects you are using, rather than relying on GC to do it for you.
This means paying attention to return values from COM interfaces, which may
be COM instances themselves. You should obviously follow the general
pattern:



Dim theObject as MyComObject = Nothing

Try

theObject = MyOtherComObject.GetAReferenceToSomething

...
Catch Ex As Exception

If theObject IsNot Nothing Then
Marshal.ReleaseComObject ( theObject )
theObject = nothing
End If

End Try


Also this error can occur if the application invoked to manage your com
objects is destroyed before the objects are themselves in VB. This means
you have VB objects alive and well but no underlying server to handle them.
When creating a new instance the server should be automagically started, but
in some instances this won't happen.
 
G

Guest

Hi Robinson,

Thanks for your info.
Pitty enough we use quite a few com-objects in that project, making it
difficult to trace the problem.
Also al com's are subclassed through our custom framework (making it more
difficult to track).
Do you have any idea on how to know which com is/are involved?

TIA,


Michael
 
R

Robinson

Hi Robinson,

Thanks for your info.
Pitty enough we use quite a few com-objects in that project, making it
difficult to trace the problem.
Also al com's are subclassed through our custom framework (making it more
difficult to track).
Do you have any idea on how to know which com is/are involved?

Hi,

To be honest I had such a headache with this kind of thing when I first
started out with interop, I now overcompenstate and go into a paranoid panic
whenever I instantiate anything COM related. The basic problem is you
have a managed COM wrapper, but the underlying object it refers to has been
destroyed. To get it clearer in your mind, here's a simple example:


Dim xlApp As Microsoft.Office.Interop.Excel.Application
Dim xlBook As Microsoft.Office.Interop.Excel.Workbook
Dim xlSheet As Microsoft.Office.Interop.Excel.Worksheet

xlApp = CType(CreateObject("Excel.Application"),
Microsoft.Office.Interop.Excel.Application)
xlBook = CType(xlApp.Workbooks.Add, Microsoft.Office.Interop.Excel.Workbook)
xlSheet = CType(xlBook.Worksheets(1),
Microsoft.Office.Interop.Excel.Worksheet)

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

' This will fail - you released xlSheet above.

xlSheet.Cells(2, 2) = "This is column B row 2"


Now, how do you debug this in your application? It's very tough. First
thing to do is look at where you are releasing COM objects. You must ensure
there aren't any references to that object elsewhere in the application.
Another way of doing this is to NEVER explicitly release the object, but to
implement the IDisposable pattern in a wrapper class to do it for you on
garbage collection. Then you can explicitly "dispose" of the object if you
want, or let GC do it when all references have been released. I *always*
implement the IDisposable pattern in any class I have that holds references
to COM objects:

Protected Overridable Sub DisposeManagedResources()

End Sub

Protected Overridable Sub DisposeUnmanagedResources()

Marshal.ReleaseComObject ( xxxxxxx )
xxxxxx = nothing

End Sub

Public Sub Dispose() Implements IDisposable.Dispose

If m_bDisposed Then
Return
End If

Me.DisposeManagedResources()
Me.DisposeUnmanagedResources()

m_bDisposed = True

GC.SuppressFinalize(Me)

End Sub

Protected Overrides Sub Finalize()

If Not m_bDisposed Then
Me.DisposeUnmanagedResources()
End If

End Sub
 
G

Guest

Hi Robinson,

Thanks for all your help.
I finally nailed down the 'COM'!
I think I now do share your com-paranoia :)


Kind regards,

Michael
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top