VS 2017 defines this interface in Microsoft.VisualStudio.Shell.Interop.15.0.DesignTime.dll:
[Guid("A459C228-5617-4136-BCBE-C282DF6D9A62")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IVsSolutionEvents7 { void OnAfterCloseFolder(string folderPath); void OnAfterLoadAllDeferredProjects(); void OnAfterOpenFolder(string folderPath); void OnBeforeCloseFolder(string folderPath); void OnQueryCloseFolder(string folderPath, ref int pfCancel); }
I want to implement this interface in my extension so that I can respond to these events, but I want the same assembly assembly to be compatible with Visual Studio 2015, so I don't need a dependency on this VS 2017 DLL. Therefore, I will copy this definition into my code.
I can get this definition from the documentation or from Visual Studio itself through F12 when I add a link to this DLL or from JustDecompile. They all give roughly the same definition of an interface.
But this interface definition does not work:
- The methods are in the wrong order, so the wrong ones are called.
- Lines are not transmitted properly - I assume they are considered BStrs, but these are LPWStrs.
- I often get an access violation after a call - my guess is the wrong calling convention.
If I applied a bunch of attributes to the interface, then it becomes the following:
[ComVisible(true)] [ComImport] [Guid("A459C228-5617-4136-BCBE-C282DF6D9A62")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IVsSolutionEvents7 { [PreserveSig, MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] int OnAfterOpenFolder([In, MarshalAs(UnmanagedType.LPWStr)] string folderPath); ...
and put the methods in the correct order, then it works.
How should you know which of these attributes to use, or which order to enter the methods? The documentation is not necessarily useful - the documentation for this interface , for example, does not add anything to the simple broken definition above.
Even if I have access to the assembly that defines the interface (Microsoft.VisualStudio.Shell.Interop.15.0.DesignTime.dll in this case), where do these attributes go? When I look at the definition in this DLL in Visual Studio or JustDecompile, I see only this simple definition, and yet, if I use the interface through a link to this DLL, it works. The attributes are somehow there, but invisible, or by default different from when I define the interface myself.
I combined the attributes that I use, from copying with load, studying IDL, and blind tests and errors, and therefore I really do not trust them. How can I do it?