Reputation: 39670
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.exe
Additional 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?
Upvotes: 2
Views: 866
Reputation: 37543
It doesn't appear that you have anything relating this section of code:
ComServerDemo csdObj = new ComServerDemo();
IComServerDemo csd = (IComServerDemo)csdObj;
In the server class you have ComServerDemo : IComServerDemo
, but in the client you don't have this relationship. Attempting this cast should fail because the compiler won't see the connection.
Edit: In agreement with @Hans Passant on type equivalence, you have redefined (re: undefined) the relationship so the type equivalence no longer holds.
Upvotes: 1
Reputation: 942119
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.
Upvotes: 2
Reputation: 103555
Well, you don't show us comclient, so I just have to guess, but I'll assume you define a class called ComServerDemo
in comclient (defined identically to the one in comserver)
But identically definitions is not the same as being the same type.
UPDATE (now that you posted comclient)
Try putting your definitions of ComServerDemo
& IComServerDemo
in your comclient
class, into the comserver
namespace.
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");
}
}
}
namespace comserver
{
[ComImport, Guid("8FDB8319-6EC3-45b4-A384-1403D3993A07")]
public class ComServerDemo
{
}
[ComImport, Guid("49752A5D-4CAD-495f-A220-07B60CDB6CE8")]
interface IComServerDemo
{
void SayHello(string name);
}
}
Upvotes: 0