As of .NET 1.1 Service Pack 1, the COM Interop layer will only allow a COM
object to talk to a .NET object if the .NET object has public visibility and
is marked [ComVisible(true)]. Prior to .NET 1.1 SP1, you could pass a class
instance to COM even if the class was internal or didn't have
[ComVisible(true)]. The only requirement used to be that the class
implement a COM interface. Now the COM Interop layer also ensures that you've
explicitly made the class visible to COM.
If you forget to do this, the COM Interop layer will throw a
System.InvalidCastException at run-time, with a message of "No such
interface supported". This error is very misleading because your class does
implement the correct interface or the code wouldn't have compiled. The
problem is that at run-time the QueryInterface from COM fails because the
COM Interop layer won't give access to a .NET object unless it is public and
marked [ComVisible(true)].
Unfortunately, this wasn't documented as part of any SP1 change that I could
find. It broke my application, and I spent a couple of frustrating days
tracking down the problem. I'm posting about it here so that maybe
Microsoft can document it and so that people searching newsgroups for this
problem can find a solution.
FWIW, I've also written an FxCop rule to check for this case in all my
assemblies. Perhaps Microsoft's FxCop team should include a similar rule.
The logic in my implementation of ITypeRule's Check method is:
if (IsComVisible(type))
{
if (!type.IsPublic)
{
return "COM types must have public visibility.";
}
}
else if (ImplementsComInterface(type) &&
!type.IsSubclassOf(typeof(Control)))
{
//The type implements a COM interface, but it isn't marked
//as visible to COM. That's almost certainly an error.
if (type.IsPublic)
{
return "Types that implement COM interfaces should use
[ComVisible(true)].";
}
else
{
return "Types that implement COM interfaces should be public and use
[ComVisible(true)].";
}
}
return null;
"Peter Huang" - 23 Sep 2004 08:39 GMT
Hi
From your description, if we do not specified the ComVisible(true), under
.net framework 1.1 sp1, the interface will be invisible to com, i.e. we can
not view it from the tlb file. Based on the MSDN, if we do not specifed the
ComVisible(false), by default the value will be true and we can see the
interface in the tlb file from the oleview tool.
using System;
using System.Runtime.InteropServices;
namespace TestCom
{
[ComVisible(false)]//If we comment it out, the interface will be visible
in tlb file. Test on .net framework 1.1 +sp1
public interface ITest
{
void Hello();
}
[ClassInterface(ClassInterfaceType.None)]
public class Class1 : ITest
{
public Class1()
{
//
// TODO: Add constructor logic here
//
}
#region ITest Members
public void Hello()
{
System.Diagnostics.Debug.WriteLine("Hello");
}
#endregion
}
}
Can you post a reproduce sample together with detailed reproduce steps, so
that we can do further troubleshooting?
If I have any misunderstanding, please feel free to let me know .
Best regards,
Peter Huang
Microsoft Online Partner Support

Signature
Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.