tags:

views:

331

answers:

5

I have a .net assembly which I am exposing to com.

the assembly has two public interfaces and one public class.

When I build the assembly I get this warning.

"(assemblyName.dll) does not contain any types that can be registered for COM Interop."

My assembly info includes the following line.

[assembly: ComVisible(true)]

Most people having this problem on the web that I have found fixed it with the above line in their assembly info. This has not helped for me.

I also tried adding [ComVisible(true)] to the class and interface definitions and it also did not help.

A: 

Did you also add the attribute [ComVisible(true)] to the class?

Beached
Also you can put the attribute on methods you want to hide from come with a [ComVisible(false)]
Beached
tried and it doesn't help and should not be necessary as the ComVisible attribute in assembly info applies to everything.
trampster
A: 

Here are a few other things to true

  • Make sure the types you want to register are marked as public
  • Add the ComVisible(true) attribute to the type directly in addition to the assembly
  • Add the Guid attribute

Not sure if the last 2 are strictly necessary but I would try them out.

JaredPar
The GUID is generated at build time based on a has of the fully-qualified class name and the identity of the assembly containing the class. ie not necessary to do this yourself.
trampster
Tried the ComVisable(true) on the types + double checked that the types are public. Still no luck.
trampster
What about adding a GUID attribute to each exposed class?
Beached
A: 

I think you need to have a strong-named assembly. Do you sign your assembly with a key file?

Further, also try specifying : [Guid("{newly generated GUID}")] [ClassInterface(ClassInterfaceType.AutoDual)]

logicnp
no I don't but it doesn't need to be strong named I have other .net assemblies which work for com interop and are not stong named.
trampster
Forgot to mention that it must also have a default parameter-less public constructor.
logicnp
+4  A: 

ComVisible classes generally need to have a public default constructor. Its members should typically also reference only ComVisible types.

You don't need to specify ComVisible(true) on the class if you have specified it at the assembly level.

However, the usual way to generate an assembly with ComVisible classes is:

  • Specify ComVisible(false) at assembly-level. Thus only classes that are explicitly marked with ComVisible(true) are exposed to COM.

  • Define an explicit ComVisible interface :

e.g.

[
ComVisible(true),
GuidAttribute("..."),
Description("...")
]
public interface IMyComVisibleType
{
        // members...
     }
  • Your ComVisible class should specify ClassInterfaceType.None, and should implement the ComVisible interface:

e.g.

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

Note that the Guid and Description attributes are not required, but useful to give you more control of the COM generation.

If the above doesn't help, try posting some sample code and I'm sure someone will be able to help.

Joe
Forgetting to add a default constructor happens to me sometimes so +1 to mention it.
Stefano Ricciardi
Adding a public default constructor did the trick however, the class in question is only ever constructed from the .net code. This was the reason no public default constructor was provided. I assume that this warning would also appear for an assembly only containing interfaces.
trampster
Yes, you'll get the same warning for an assembly with only interfaces. I guess it's similar to the way a VB6 ActiveX DLL must contain at least one publicly creatable class. But it seems unnecessarily restrictive in the .NET world, as you could have a class constructed by managed code and passed to a COM component e.g. as a method argument.
Joe
+1 for the default constructor.
Bob Nadler
A: 

I ran into the default constructor problem. What fooled me was that the type library file will contain the class GUID reference even though that class is not being registered. A quick way to see what will be registered is to create a registry file ('assembly.reg') like this:

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

There's a good discussion of exposing interfaces in COM Interop: Base class properties not exposed to COM. Some example code is here: Exposing .NET Components to COM.

Bob Nadler