开发者

Marshal.ReleaseComObject throws exception

Trying to use a COM visible .NET class via other .NET application and get exception:

Message: The object's type must be __ComObject or derived from __ComObject.

Parameter name: o

Stack Trace: at System.Runtime.InteropServices.Marshal.ReleaseComObject(Object o)

The class looks as follows:

[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IViewer : IComInteropDefinedI开发者_开发技巧nterface
{
}

[ClassInterface(ClassInterfaceType.None)]
[ComVisible(true)]
[Guid("[some guid]")]
public class MyViewer : UserControl, IViewer    
{
    //IViewer implementation
}

I register the component with:

regasm [Assembly Path] /tlb /codebase

The client application, which is also in .NET instantiates successfully the given class, but when he callsMarshal.ReleaseComObject() it gets the exception described above.

Any idea for solving this problem?

EDIT: Unfortunately I can't provide the client application code for instantiating my object. However I know the client is using the same method to instantiate real COM objects.


I got this problem recently, when reimplementing a native COM to managed code. The solution was to ask if the object is a native COM with Marshal.IsComObject, only native COMs must be release with Marshal.ReleaseComObject.

This is code:

if (Marshal.IsComObject(comObject))
{
     Marshal.ReleaseComObject(comObject);
}
comObject = null;

Important: you have to be sure, no use that object after been Released.

For a more detailed explanation read this post: http://blogs.msdn.com/b/visualstudio/archive/2010/03/01/marshal-releasecomobject-considered-dangerous.aspx


But how are you creating the class instance? Simply using the expression new MyViewer() doesn't create a COM object. Instead it creates a plain old .Net object which cannot be used with the ReleaseComObject method.

Based on your sample code, in particular the line about MyViewer having an implementation, it doesn't sound like you're dealing with a COM object. Instead it looks like you have a managed object which implements a COM interface.

In order to use the ReleaseComObject you'd need to actually have a COM / RCW object.


My guess would be that you are actually not using COM but simply use a referenced .NET class. If your project contains code like

MyViewer viewer = new MyViewer();

and you have added the library containing MyViewer not as a COM reference, you are actually not using COM.


I would rather try:

if (comObject != null)
{
      if (System.Runtime.InteropServices.Marshal.IsComObject(comObject))
      {                
          System.Runtime.InteropServices.Marshal.ReleaseComObject(comObject);
      }
      comObject= null;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜