We have developed a .NET Assembly named XXadapter. The goal is to have XXadapter act as a COM object to unmanaged clients. XXadapter class implements a C++ COM IDL-defined interface. The C++ COM object was added as a reference to the C# project, thus exposing COM API via Interop. Therefore, class interface _XXadapter interface was generated by COM Interop, and used by unmanaged clients.
Everything was good until I tried to migrate XXadapter project from VS2010 to VS2012(Please note that there are NO source code changes). _XXadapter's uuid and some of method's DispID in _XXadapter have been changed.
This is the XXadapter class's properties:
[ComVisible(true)]
[ComSourceInterfaces( typeof( _IBaseEvents ) )]
[ClassInterface(ClassInterfaceType.AutoDual)]
[Guid("class ID")]
public partial class XXadapter : ICOMInterface
{
...
}
Here is the _XXadapter definition in type library(viewed by oleview.exe) before migration:
[
odl,
uuid(E8******-****-****-****-************),
hidden,
dual,
nonextensible,
oleautomation,
custom(123456-1234-1234-1234-123456789012, CompanyName.XXadapter)
]
interface _XXadapter : IDispatch {
[id(00000000), propget,
custom(654321-4321-4321-4321-210987654321, 1)]
HRESULT ToString([out, retval] BSTR* pRetVal);
[id(0x60020001)]
HRESULT Equals(
[in] VARIANT obj,
[out, retval] VARIANT_BOOL* pRetVal);
[id(0x60020002)]
HRESULT GetHashCode([out, retval] long* pRetVal);
[id(0x60020003)]
HRESULT GetType([out, retval] _Type** pRetVal);
[id(0x60020004)]
HRESULT GetVersion([out, retval] BSTR* pRetVal);
[id(0x60020005)]
HRESULT Method_one(...);
[id(0x60020006)]
HRESULT Method_two(...);
...
[id(0x6002000e)]
HRESULT Method_three(...);
[id(0x6002000f)]
HRESULT Method_four();
[id(0x60020010)]
HRESULT Method_five(...);
...
};
After migration, the _XXadapter defined as
[
odl,
uuid(E6****-****-****-****-************),
hidden,
dual,
nonextensible,
oleautomation,
custom(123456-1234-1234-1234-123456789012, CompanyName.XXadapter)
]
interface _XXadapter : IDispatch {
[id(00000000), propget,
custom(654321-4321-4321-4321-210987654321, 1)]
HRESULT ToString([out, retval] BSTR* pRetVal);
[id(0x60020001)]
HRESULT Equals(
[in] VARIANT obj,
[out, retval] VARIANT_BOOL* pRetVal);
[id(0x60020002)]
HRESULT GetHashCode([out, retval] long* pRetVal);
[id(0x60020003)]
HRESULT GetType([out, retval] _Type** pRetVal);
[id(0x60020004)]
HRESULT GetVersion([out, retval] BSTR* pRetVal);
[id(0x60020005)]
HRESULT Method_three(...);
[id(0x60020006)]
HRESULT Method_four(...);
[id(0x60020007)]
HRESULT Method_five(...);
[id(0x60020008)]
HRESULT Method_one(...);
[id(0x60020009)]
HRESULT Method_two(...);
...
};
Not only the uuid of _XXadapter has been changed, but also the DispID of all the Methods_XXXX().
As a result the _XXadapter assembly has lost its backwards compatibility with its COM clients.
By investigating and googling for this issue, I found the reordering of Method_three/four/five() in type library could be caused by these three methods are partially declared in a separate file. I have tried to move the declaration for all COM visible methods into the same file, this problem can be solved. However, this makes a huge file which we originally wanted to avoid. Is there any solution to keep the backwards compatibility without moving COM visible methods? Does anyone know the root cause of reordering the methods? Thank you so much.
[ComVisible(true)] [ComSourceInterfaces( typeof( _IXXXEvents ) )] [ClassInterface(ClassInterfaceType.AutoDual)] [Guid("15******-****-****-****-************")] public partial class XXadapter : IXXVersion{...}
– Chloenew
keyword. See my thoughts about it in the comments to my answer. – noseratio