COM Interop 注册

6
我有一个.NET程序集,我正在将其暴露给COM。该程序集有两个公共接口和一个公共类。当我构建程序集时,我收到以下警告:

(assemblyName.dll) 不包含任何可以注册为COM互操作的类型。

我的程序集信息包括以下行。

[assembly: ComVisible(true)]

我发现大多数在网上遇到这个问题的人都通过在程序集信息中添加上述代码行来解决。但这对我没有帮助。

我还尝试在类和接口定义中添加[ComVisible(true)],但也没有帮助。

5个回答

15

ComVisible的类通常需要一个公共的默认构造函数。其成员通常也只引用ComVisible类型。

如果您已经在程序集级别上指定了ComVisible(true),则不需要在类上指定。

然而,生成包含ComVisible类的程序集的通常方法是:

  • 在程序集级别上指定ComVisible(false)。因此,只有明确标记为ComVisible(true)的类才会暴露给COM。

  • 定义一个明确的ComVisible接口:

例如:

[
ComVisible(true),
GuidAttribute("..."),
Description("...")
]
public interface IMyComVisibleType
{
        // members...
     }
  • 你的ComVisible类应指定ClassInterfaceType.None,并实现ComVisible接口:

例如:

     [
     ComVisible(true),
     GuidAttribute("..."),
     ClassInterface(ClassInterfaceType.None)
     ]
     public sealed class MyComVisibleType : IMyComVisibleType
     {
        // implementation ...
     }

请注意,Guid和Description属性不是必需的,但可以让您更好地控制COM生成。

如果以上内容无法帮助您,请尝试发布一些示例代码,我相信有人能够帮助您。


1
有时候我会忘记添加默认构造函数,所以提到它是很重要的。 - Stefano Ricciardi
1
添加一个公共默认构造函数就解决了问题,但是,所涉及的类只能从 .net 代码中构造。这就是为什么没有提供公共默认构造函数的原因。我认为,如果一个程序集只包含接口,也会出现这个警告。 - trampster
是的,对于仅包含接口的程序集,您将收到相同的警告。我猜这类似于VB6 ActiveX DLL必须至少包含一个可公开创建的类的方式。但是,在.NET世界中,它似乎是不必要限制的,因为您可以通过托管代码构造类,并将其作为方法参数传递给COM组件。 - Joe
我在使用GuidAttribute时遇到了UUID格式的问题,这个链接帮助我解决了它:https://msdn.microsoft.com/en-us/library/b0e48ss8.aspx - AleX_

3

我遇到了默认构造函数的问题。让我困惑的是,即使该类没有被注册,类型库文件仍将包含类GUID引用。查看将要注册的内容的快速方法是创建一个名为“assembly.reg”的注册表文件,如下所示:

regasm assembly.dll /regfile:assembly.reg /codebase

COM Interop: Base class properties not exposed to COM中有一次关于接口暴露的很好的讨论。这里提供了一些示例代码:将.NET组件公开给COM


0

以下是一些其他需要注意的事项:

  • 确保您想要注册的类型已标记为公共的
  • 除了程序集之外,还应直接在类型中添加ComVisible(true)特性
  • 添加Guid特性

不确定最后两个是否严格必要,但建议尝试。


GUID是根据完全限定类名和包含该类的程序集的标识符的哈希值在构建时生成的,因此不需要自己进行此操作。 - trampster
尝试在类型上使用ComVisible(true),并再次确认类型为public。仍然没有成功。 - trampster
每个公开类添加一个GUID属性怎么样? - Beached

0

我认为你需要一个强名称程序集。你有用密钥文件签名程序集吗?

此外,还可以尝试指定: [Guid("{新生成的 GUID}")] [ClassInterface(ClassInterfaceType.AutoDual)]


不需要强名称,我有其他的.NET程序集可以用于COM互操作,并且它们没有强名称。 - trampster
忘了提到它还必须有一个默认的无参公共构造函数。 - logicnp

0

在我的 C# 项目中勾选“注册 COM 互操作”的选项后,我遇到了同样的问题。这有一个简单的解决方案:

在解决方案资源管理器中,进入属性文件夹。打开AssemblyInfo.cs文件。滚动到一行上面写着: [assembly: ComVisible(false)]

将其更改为: [assembly: ComVisible(true)]

这将消除警告消息,并允许创建.tlb文件,从而使.NET代码对COM可见。
如果您不想使整个程序集支持COM,则可以按照其他提示之一进行操作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接