0

I'm developing a .net-Component (.dll) that needs to act as as server for two clients: one of them is c++-native and one is .net.

To get the native-client use the server, the server has a COM-Interface and is registered via regasm:

[
Guid("B9BE47C8-2838-4449-B2C4-22B07F52EEA6"),
InterfaceType(ComInterfaceType.InterfaceIsDual),
ContractClass(typeof(IComMethodsLicenseServerContracts)),
ComVisible(true)
]
public interface ILicenseServer{...}

The native-client imports it via #import "server.tlb" named_guids into the client

I thought the .net-client can use the com-interface as well but right know I learnd that tlbim does not work with .net-dlls so the client has to use it like a regular .net-reference.

On the target machine both Clients can be installed together or seperately. To avoid version-conflicts I need to have the server-component only once at the target machine. I thought I have to let the setup put the server-component somewhere in %program files%\common-files at the target machine and register it but that doesn't seem to work for the .net-client (since it does not use COM so it wont find the server).

Whats the thing to do here? Is it the right solution to but the server (and all it's dependencies) into the GAC of the target machine? If so, how to regasm it as a COM-Component for the native-client? Do I have to know the exact path of the GAC?

Seems like I'm a bit stucked ;-(

suriel
  • 191
  • 1
  • 10
  • It's never mandatory to put a .NET dll in the GAC. You can register the .NET assembly using "regasm /codebase ...". As for to be able to use the same COM interface with two types of clients, what you could do is create a separate .tlb (using midl for example), and reference that from .NET (COM reference) and from native (#import). In both world you can implement that interface. – Simon Mourier Sep 08 '20 at 12:32
  • @SimonMourier I cannot reference a tlb of a .net-COM-Server from a .net-project to get COM-access. Whenever I try to build the .net-wrapper around the com-server via `tlbtimp` it gives me `error TI1029 : Type library 'LicenseServer' was exported from a CLR assembly and cannot be re-imported as a CLR assembly.` – suriel Sep 08 '20 at 13:11
  • The .tlb you could use in both .NET and native projects (that can contain common stuff for both projects) should not be built with .NET, but with MIDL: https://stackoverflow.com/questions/30269119/how-do-i-invoke-the-midl-compiler-to-generate-a-tlb-file-type-library-from-an – Simon Mourier Sep 08 '20 at 13:23
  • If I'm right,midl can only process .idl-files? I don't have an .idl because it's a .net-dll. The tlb from the DLL, which is generated by visual studio, cannot get imported by an .net-project as a com-server. It can only be used as a regular .net-reference which gets copied to the output-directory of the client – suriel Sep 08 '20 at 18:54
  • I know you don't have an idl but you can write one, process it using MIDL and you'll get a .tlb that you will be able to import using Visual Studio for a .NET project and in a native project too. It's just a text file. If you want an example, use OleView from the Windows SDK on the .tlb you have created using .NET, it will show you a corresponding .idl. – Simon Mourier Sep 09 '20 at 06:11
  • @suriel `it does not use COM so it wont find the server` You could have the client assembly lookup the COM info in the registry to locate the shared component, then use [AssemblyResolve](https://learn.microsoft.com/en-us/dotnet/api/system.appdomain.assemblyresolve?view=netframework-4.8) to load it. – dxiv Sep 09 '20 at 07:40
  • @simon: despite the fact that it would be way to much work to always keep the .net-interface and .idl in sync, it still does not work. when trying to export the .idl from oleview, create an tlb with midl and tlbimp it, I get the error `TlbImp : error TI1035 : Type 'LicenseServer' from type library 'LicenseServer' is trying to implement class interface '_Object' from type library 'mscorlib', which was exported by TlbExp. This scenario is not supported.` I think it's just not possible to use a Com-Component written in .net with another .net-client, so my plan was to use it as a regular reference – suriel Sep 09 '20 at 08:02
  • @dxiv that would mean the client should use late-bindung without any compiletime-checking of methodnames/-signatures? – suriel Sep 09 '20 at 08:22
  • You don't really get it. The thing is to create a COM interface independently from any language as that's what COM is about, and reference it from both worlds, there's no "keep in sync" work to do. 1) Copy paste the idl code in my previous link in a test.idl file, 2) run midl test.idl, this will create a test.tlb, 3) reference that in a .NET project, and now you can create a ComVisible class that implements that MyLibrary.IFoo interface. Any other program that know COM can also reference or implement these interfaces using either the .TLB: delphi, .NET, VC's #import, etc. – Simon Mourier Sep 09 '20 at 08:36
  • @SimonMourier you mean I must NOT define the COM-Interface of the server in c# as an C#-ComVisible-Interface but an via IDL -> midl -> import the tlb to the .net-com-server -> Implement the interface(s)? That would mean twiddeling around with the IDL-Syntax, bit it may be worth looking at it, yes. Thank you. After all: whats wrong with my initial approach to put the Server into the GAC and use it as a regular .net-reference? – suriel Sep 09 '20 at 09:31
  • Exactly. Of course you can always use a regular .NET ref as well, with an external .tlb or not, that's your call (GAC is always optional). I was answering the "how to use COM objects implemented in .NET with native and .NET programs" question. – Simon Mourier Sep 09 '20 at 09:47
  • ok thank you. the question was intended as "how to use a .net-dll from .net, which is also used as a com-server by another (native) client". Its not a MUST to use its com-interface. But if its located somewhere under "common files" and NOT in the GAC, I think the net-client will not find it at runtime, isn't it? – suriel Sep 09 '20 at 10:28
  • @suriel Nothing would change as far as project references, compile time checks etc. It's just that at runtime you get to choose where to load the assembly from. – dxiv Sep 09 '20 at 17:17

0 Answers0