4

尝试通过其他 .NET 应用程序使用 COM 可见 .NET 类并获得异常:

消息:对象的类型必须是 __ComObject 或派生自 __ComObject。

参数名称:o

堆栈跟踪:在 System.Runtime.InteropServices.Marshal.ReleaseComObject(Object o)

该类如下所示:

[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IViewer : IComInteropDefinedInterface
{
}

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

我使用以下方式注册组件:

regasm [Assembly Path] /tlb /codebase

同样在 .NET 中的客户端应用程序成功地实例化了给定的类,但是当他调用Marshal.ReleaseComObject()它时,会出现上述异常。

有解决这个问题的想法吗?

编辑: 不幸的是,我无法提供用于实例化我的对象的客户端应用程序代码。但是我知道客户端使用相同的方法来实例化真正的 COM 对象。

4

4 回答 4

3

我最近在将本机 COM 重新实现到托管代码时遇到了这个问题。解决方案是使用 Marshal.IsComObject 询问对象是否是本机 COM,只有本机 COM 必须使用 Marshal.ReleaseComObject 释放。

这是代码:

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

重要提示:您必须确定,发布后不要使用该对象。

有关更详细的解释,请阅读这篇文章:http: //blogs.msdn.com/b/visualstudio/archive/2010/03/01/marshal-releasecomobject-considered-dangerous.aspx

于 2013-07-02T21:26:15.557 回答
0

我的猜测是您实际上并没有使用 COM,而只是使用了引用的 .NET 类。如果您的项目包含类似的代码

MyViewer viewer = new MyViewer();

并且您添加了包含MyViewernot 作为 COM 引用的库,实际上您并没有使用 COM。

于 2010-08-24T08:31:11.817 回答
0

但是你是如何创建类实例的呢?简单地使用表达式new MyViewer()不会创建 COM 对象。相反,它会创建一个普通的旧 .Net 对象,该对象不能与 ReleaseComObject 方法一起使用。

根据您的示例代码,尤其是关于MyViewer实现的那一行,听起来您不是在处理 COM 对象。相反,看起来您有一个实现 COM 接口的托管对象。

为了使用 ReleaseComObject 您实际上需要一个 COM / RCW 对象。

于 2010-08-24T08:28:54.930 回答
0

我宁愿尝试:

if (comObject != null)
{
      if (System.Runtime.InteropServices.Marshal.IsComObject(comObject))
      {                
          System.Runtime.InteropServices.Marshal.ReleaseComObject(comObject);
      }
      comObject= null;
}
于 2018-12-19T12:02:21.193 回答