Click here to Skip to main content
16,017,502 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello

I'm toying with the idea of ​​using COM as inter-process communication between C# applications/modules. In the second step as a COM service.

BIG advantage: Calls to methods and callbacks (events) can directly checked by compiler at compile time.

Disadvantages: Old technology, not really build for C#

In the internet you can find a few samples of a C# implemented COM server. A runtime creation works like
C#
var obj = Activator.CreateInstance(Type.GetTypeFromProgID("Server.MyClass", true));
Console.WriteLine(obj.GetType().InvokeMember("SomeMethod", BindingFlags.InvokeMethod, null, obj, null));


So far, so good. The executable file can find COM via the registry and thus start it.

But I don't like method names as strings. This is very dangerous when methods are deleted or renamed. A better solution would be to use the IDL/TLB information directly by adding a reference to the server's interop assembly in the client. After adding, the compiler now knows the interfaces and classes, but the server is now loaded into the client's process like a inproc dll.

C#
MyClass obj = new MyClass();
Console.WriteLine(obj.SomeMethod());


This seems only to work, if the server is written in C++. Then you can refer to the generated interop assembly through tlbimp. But you can't create a additional interop assembly from a COM assemply. A tlbexp and a afterward tlbimp is not possible. Tlbimp says, that the tlb is already created from a COM assembly.

Two questions:
a) Is it technical possible to start a C# server out of process?
b) Is it (still) appropriate to use COM for this?

Your expertise and opinion is needed!

What I have tried:

Playing with sample projects..
Posted
Comments
Richard Deeming 7-Jun-24 4:19am    
If you're using .NET Framework, there's no need to use COM for IPC; there is built-in support for IPC channels to enable efficient communication between processes on the same machine:
System.Runtime.Remoting.Channels.Ipc Namespace | Microsoft Learn[^]

There are also classes for named and anonymous pipes, which still work in the latest version of .NET:
Pipe Operations in .NET - .NET | Microsoft Learn[^]

Or you could build something using gRPC[^].
Michael Sabo 7-Jun-24 8:16am    
Regrettable that the classes/technology no longer exist in .NET Core.
Richard Deeming 7-Jun-24 8:17am    
The IPC channels don't. But the named/anonymous pipes still exist, and gRPC supports .NET Core as well.

1 solution

You can - but that's going to depend on having registered the COM object as out-of-process. Suppose you have a COM class in bob.exe. Register it with regsvr32 /u /RegServer bob.exe. At that point, the COM classes in the assembly are registered to run out-of-process.

If you know the progid, you should be able to get a runtime instance of the object using:
C#
Type bobType = Type.GetTyprFromProgId(bobProgId, true);
object bobObject = Activator.CreateInstance(bobType);
Then, to call the methods you should be able to do something like this:
C#
string whoIsCodeProject = (string)bobObject.InvokeMember("WhatIsChrisReallyCalled", BindingFlags.InvokeMethod, null, bobObject, new object[] { 42 });
You can see that I'm calling a method and passing in a value of 42 because the COM method expects the magic H2G2 number.

Note, I've entered the code directly here from memory (to the technique), so there may be a minor error here or there.

Now, the question is, would I recommend doing this? Well no. There are so many other technologies that you could use. For strongly named connections, I like Protobuf and that would be my goto technology there. The only reason I would be using COM is if I were communicating with something that absolutely had to be COM.
 
Share this answer
 
v3
Comments
Michael Sabo 7-Jun-24 8:12am    
As mentioned above, I don't like calls as strings.
Pete O'Hanlon 7-Jun-24 8:18am    
You answered me as I was adding - I really wouldn't be recommending COM; I would rather use something like Protobuf.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900