I have two separate projects (comclient and comserver), with some very simple code:
comserver/Program.cs
using System;
using System.Reflection;
using System.Runtime.InteropServices;
namespace comserver
{
class Program
{
static void Main(string[] args)
{
RegisterComObject();
}
public static void RegisterComObject()
{
Assembly asm = Assembly.GetExecutingAssembly();
RegistrationServices reg = new RegistrationServices();
bool f = reg.RegisterAssembly(asm, AssemblyRegistrationFlags.SetCodeBase);
Console.WriteLine("RegisterAssembly: {0}", f ? "ok" : "fail");
}
}
[ComVisible(true)]
[Guid("49752A5D-4CAD-495f-A220-07B60CDB6CE8")]
interface IComServerDemo
{
void SayHello(string name);
}
[ComVisible(true)]
[Guid("8FDB8319-6EC3-45b4-A384-1403D3993A07")]
public class ComServerDemo : IComServerDemo
{
public void SayHello(string name)
{
Console.WriteLine("Hello {0}!", name);
}
}
}
comclient/Program.cs
using System;
using System.Runtime.InteropServices;
namespace comclient
{
class Program
{
static void Main(string[] args)
{
ComServerDemo csdObj = new ComServerDemo();
IComServerDemo csd = (IComServerDemo)csdObj;
csd.SayHello("Bob");
}
}
[ComImport, Guid("8FDB8319-6EC3-45b4-A384-1403D3993A07")]
public class ComServerDemo
{
}
[ComImport, Guid("49752A5D-4CAD-495f-A220-07B60CDB6CE8")]
interface IComServerDemo
{
void SayHello(string name);
}
}
When I run comserver.exe, it registers the COM interface OK:
RegisterAssembly: ok
But when I try to run the COM client, I get this exception:
An unhandled exception of type
‘System.InvalidCastException’ occurred
in comclient.exeAdditional information: Unable to cast
object of type
‘comserver.ComServerDemo’ to type
‘comclient.ComServerDemo’.
Any ideas why I’m getting this exception? The comclient project does not reference the comserver class. Also, I’m trying to create an out of proc COM server, but I have a feeling this might not do the trick – any ideas about this also?
You need a feature called ‘Type equivalence’, added to .NET 4.0. It is used to allow two distinct .NET types to be considered equivalent when they have the exact same GUID. This feature was used to implement the new ‘Embed Interop Types’ feature, making it unnecessary to deploy PIAs.
I don’t know enough about it to judge whether you can actually use it to make this code work. Gut instinct says yes. Check out the docs for the [TypeIdentifier] attribute.