0

I'm quite struggling when trying to to what follows.

I'm currently using an ActiveX, through an interop dll generated by Visual Studio (more precisely tlbimp, implicitly).

Different versions of this ActiveX exist, that sometimes add, remove, properties in the interfaces. If I want to change the version, I have to change the reference, recompile and so on.

I'd like to have a single version of my code. I remember that to drive Word for example, one can instantiate a word object via CreateInstance on Word.Application, and call methods, whatever the version. Calls being linked only at runtime. I'd like to do the same with the activeX I use, but I don't really know how to do that (btw, it's sage objets100c dll). I don't find it in the list of ActiveX, thus I'm not even sure I can do like for Word.Application.

Has someone a clue about how I could do that ? (might be a completely different solution, as my need is: having one code with no need to recompile).

Thank you in advance

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Poc
  • 109
  • 10
  • 1
    You can use the C# `dynamic` keyword: https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/types/using-type-dynamic#com-interop but if you use the library a lot it can be a pain. Otherwise you can use the lowest version TLB as a basis and use dynamic only when using newer properties/methods. – Simon Mourier Mar 01 '21 at 14:21
  • 1
    @SimonMourier Merci Simon :) I couldn't use the tlb as a basis because v2 (for example) adds new values to the enums, new methods in the interfaces and so on, (and someone removes them) making them incompatible. I found another way, reflecting interop dll to generate a kind of intermediate layer using dynamic objects, by code. If I may, I'm honored you answered to my question, I used your HAP library lots of time in the past for different personal projects, it's been very useful. – Poc Mar 07 '21 at 00:29

1 Answers1

1

If you have a corresponding *.tlb file, reference this one, not the dll. In the properties window of the reference, you can set the Specific Version property to False and EmbedInterop Types to True (makes it more stable).

If this does not help, you can try to create and access the object dynamically instead of adding a reference. You need either the ProgID of the COM type …

Type comType = Type.GetTypeFromProgID("MyProg.ProgId");

… or the CLSID of the COM type (you may find them in the registry)

Type comType = Type.GetTypeFromCLSID(new Guid("EA2BACD6-9D0F-4819-98BC-88E8173D3D16"));

Then you can create and object with Activator.CreateInstance and assign it to a dynamic to do late binding.

dynamic sage100 = Activator.CreateInstance(comType);

You will get no IntelliSense for this dynamic object. If you specify non-existing members (method or property names), you can still compile and run your C# code; however, a run-time exception will be thrown when you attempt to access these members.

Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188
  • 1
    Hi Olivier, Thank you for the different points you list here. Actually I had these steps in my code but couldn't glue them together: the Guid obtained by disassembling an interop dll didn't work with GetTypeFromProgId, looking into the registry gave me Guid that didn't work with GetTypeFromCLSID. Eventually I found a ProgId to use,with GetTypeFromProgId in a forum, (listing the registered ActiveX didn't give me it) and found a way to manage the versions while maintaining Intellisense. Anyway, I mark your answer as correct :) – Poc Mar 07 '21 at 00:21