0

I'm trying to understand how the Visual Studio EnvDTE Interop Assemblies work, and why they have been designed this way. New assemblies contain updated/new interfaces, and the recommendation by Microsoft is to use the most recent interface in VS2017. That looks like this:

EnvDTE.DTE dte = (EnvDTE.DTE)((IServiceProvider)Host).GetCOMService(typeof(DTE));
EnvDTE80.DTE2 dte2 = (EnvDTE80)dte;
EnvDTE.Solution solution = dte2.Solution; // Returns a Solution type, not Solution2
EnvDTE80.Solution2 solution2 = (EnvDTE80.Solution2)dte2.Solution; 

In that snippet,the DTE2.Solution property returns type Solution and not Solution2 as I'd have expected... You must explicitly cast to access newer interfaces, which seems odd.

I searched the registry for each GUID of the EnvDTExxx assemblies, but the only CLSIDs I found with references to any of them were the Microsoft Visual Studio DTE Object and the Microsoft Visual Studio Solution Object. Both link to EnvDTE as their type library... And I can't find any COM object that uses the newer EnvDTExxx versions. Yet I see the newest interfaced in OleView!!! :

DTE2 is Available

Does this mean newer EvDTExxx Assemblies rely on the origional EnvDTE to access the actual COM component? I believe the interfaces in OleView represent the actual interfaces on the COM component... but then why wouldn't the EnvDTE type library use the updated DTE2 interface?

To add to my confusion, I discovered only EnvDTE and EnvDTE80 are decorated with the PrimaryInteropAssemblyAttribute... while EnvDTE90-100 aren't! I'm assuming because the newer interop assemblies only expose types of EnvDTE (The PIA), there won't be type conflicts? But that doesn't explain why EnvDTE80 is marked as a PIA also...I thought there could only be one PIA!

Please rescue me from my COMfusion!

FakeSaint
  • 492
  • 5
  • 8
  • 1
    possible still useful to read despite it's age: https://stackoverflow.com/questions/27448122/what-is-the-difference-between-these-methods-of-getting-dte2-visual-studio-2013 – jazb Nov 16 '18 at 02:51
  • Thanks, but I know how to get the updated interfaces. I just don't understand why they've been designed this way... It seems like they are releasing 2 PIA's for the same COM object, and then releasing non-Primary interop assemblies that reference the PIA's? The OleView of the COM object seems to show the type exposed by the newest PIA, but the old PIA is listed as the type library for the COM object – FakeSaint Nov 16 '18 at 03:02

1 Answers1

2

Com types really are just interfaces, and it follows the same rules as .NET interfaces.

In a interface you can't change the return type of a defined method in a derived method without breaking binary compatibility.

So because the interfaces are essentially

public interface EnvDTE 
{
    Solution Solution {get;}
    //other stuff
}

public EnvDTE80 : EnvDTE
{
    //more other stuff
}

the return must be the same to keep binary compatibility.

Scott Chamberlain
  • 124,994
  • 33
  • 282
  • 431
  • Thanks! Sorry I don't think I've done my question justice. My confusion is why additional interop assemblies are being added in the first place (with one as a PIA and the rest not), and why they aren't returning the most recent types. I understand what you are saying though, but they could'nt they have just included new methods with the correct return type? – FakeSaint Nov 16 '18 at 03:30
  • They can't return the most recent types. You are working with interfaces, and the interface contract states it returns the original old type. As for why they are not marked PIA I have no idea. – Scott Chamberlain Nov 16 '18 at 03:33