none
Keep compatibility of com-interop called by vb6 (ComVisible and Guid not working) RRS feed

  • Question

  • Hi,

    We have a vb6 application that calls a c# com interop.
    In our new version we have added a new function to the com interop, and now the vb6 app is failing with "Run-time error 430 class does not support Automation or does not support expected interface"

    the code looks like:

    [ComVisible(true), Guid("682D4AF6-E607-3112-87B2-B7B1A58D2618")]
    [ServiceContract]
    public interface IMyInterface
    {
     ...

     [OperationContract]
            string NewFunction();
    }

    [ComVisible(true), Guid("7E99EAC4-C7FA-4e0e-9996-F4500E17AF69")]
    [ClassInterface(ClassInterfaceType.AutoDual)]
    public class MyClass:IMyInterface
    {
     ...

     public string NewFunction() {...}
    }

    when comparing old and new IDL files it show that the Guids of the class are the same:
        [
          uuid(7E99EAC4-C7FA-4E0E-9996-F4500E17AF69),
          version(1.0),
            custom({0F21F359-AB84-41E8-9A78-36D110E6D2F9}, "MyCompany.MyServiceClient.MyClass")
        ]
        coclass SecureAssets {
            [default] interface _MyClass;
            interface _Object;
            interface IMyInterfaces;
        };

    also the Guids of the interface are the same:
         [
            odl,
            uuid(682D4AF6-E607-3112-87B2-B7B1A58D2618),
            version(1.0),
            dual,
            oleautomation,
             custom({0F21F359-AB84-41E8-9A78-36D110E6D2F9}, "MyCompany.MyService.Contracts.IMyInterface")   
         ]
         interface IMyInterfaces : IDispatch {
     
    but there is another definition marked hidden, and there the Guid of the new one is different:
         [
            odl,
            uuid(648140BD-2089-331A-B947-6E03DF2DDF4F),
            hidden,
            dual,
            nonextensible,
            oleautomation,
             custom({0F21F359-AB84-41E8-9A78-36D110E6D2F9}, "MyCompany.MyServiceClient.MyClass")   
         ]
        interface _MyClass : IDispatch {

    Important note: when we released the first version we did not set ComVisible and Guid for the interface (only for the class)

    any idea how can we force this Guid to be the same as the one from the first version??

    Thanks,
    PR

    • Edited by Talya Klain Sunday, November 28, 2010 8:17 AM
    Thursday, November 18, 2010 4:56 PM

Answers

  • Hello Pavel,

     

    1. The problem lies in the fact that "MyClass" is given the "AutoDual" ClassInterfaceAttribute :

    [ComVisible(true), Guid("7E99EAC4-C7FA-4e0e-9996-F4500E17AF69")]
    [ClassInterface(ClassInterfaceType.AutoDual)]
    public class MyClass:IMyInterface
    {
    ...
    }

    1.1 Choosing this option limits the changes that can be made to the "MyClass" class. You and the clients are commited to the current layout of the methods exposed by the class interface for "MyClass" (i.e. the _MyClass interface).

    1.2 The drastic effect of change (e.g. by adding in new members) is the breaking of compatibility for existing client applications.

    1.3 I believe that the GUID for the _MyClass class interface changed as a result of the addition of the new NewFunction() method. You can verify this by commenting out the new NewFunction() (in IMyInterface) and then recompiling and re-doing regasm.exe. Via OleView, you will see that the old GUID is re-instated for the _MyClass interface.

     

    2. >> any idea how can we force this Guid to be the same as the one from the first version??

    2.1 I suggest that you do not use any class interface at all. To do this, use the ClassInterfaceType.None option for the ClassInterfaceAttribute :

    ClassInterface(ClassInterfaceType.None)

    2.2 By using ClassInterfaceType.None, you expose functionality for the MyClass class through interfaces implemented explicitly by MyClass.

    2.3 The default interface for MyClass is thus IMyInterfaces. And since it has been marked with a specific GUID, this GUID will remain the same even if you add new methods to IMyInterfaces.

    2.4 After you have used ClassInterfaceType.None, make sure to recompile the VB6 client application using the new Type Library for the C# COM interop DLL.

    2.5 After recompiling, you may add new methods to IMyInterfaces without breaking existing client apps. 

     

    - Bio

     

    • Marked as answer by eryang Friday, November 26, 2010 3:24 AM
    Friday, November 19, 2010 9:26 PM

All replies

  • Hello Pavel,

     

    1. The problem lies in the fact that "MyClass" is given the "AutoDual" ClassInterfaceAttribute :

    [ComVisible(true), Guid("7E99EAC4-C7FA-4e0e-9996-F4500E17AF69")]
    [ClassInterface(ClassInterfaceType.AutoDual)]
    public class MyClass:IMyInterface
    {
    ...
    }

    1.1 Choosing this option limits the changes that can be made to the "MyClass" class. You and the clients are commited to the current layout of the methods exposed by the class interface for "MyClass" (i.e. the _MyClass interface).

    1.2 The drastic effect of change (e.g. by adding in new members) is the breaking of compatibility for existing client applications.

    1.3 I believe that the GUID for the _MyClass class interface changed as a result of the addition of the new NewFunction() method. You can verify this by commenting out the new NewFunction() (in IMyInterface) and then recompiling and re-doing regasm.exe. Via OleView, you will see that the old GUID is re-instated for the _MyClass interface.

     

    2. >> any idea how can we force this Guid to be the same as the one from the first version??

    2.1 I suggest that you do not use any class interface at all. To do this, use the ClassInterfaceType.None option for the ClassInterfaceAttribute :

    ClassInterface(ClassInterfaceType.None)

    2.2 By using ClassInterfaceType.None, you expose functionality for the MyClass class through interfaces implemented explicitly by MyClass.

    2.3 The default interface for MyClass is thus IMyInterfaces. And since it has been marked with a specific GUID, this GUID will remain the same even if you add new methods to IMyInterfaces.

    2.4 After you have used ClassInterfaceType.None, make sure to recompile the VB6 client application using the new Type Library for the C# COM interop DLL.

    2.5 After recompiling, you may add new methods to IMyInterfaces without breaking existing client apps. 

     

    - Bio

     

    • Marked as answer by eryang Friday, November 26, 2010 3:24 AM
    Friday, November 19, 2010 9:26 PM
  • Hi PR,

    I'm writing to check the issue status, please feel free to let us know if you have any concern.


    Sincerely,
    Eric
    MSDN Subscriber Support in Forum
    If you have any feedback of our support, please contact msdnmg@microsoft.com.
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Tuesday, November 23, 2010 2:01 AM
  • Bio,

    Thanks for the reply.

    It helped us a lot understanding what we were doing wrong.

    Things are now working for us.

    PR

    Sunday, November 28, 2010 8:25 AM
  • I'd like to add that to keep compatibility, you should add new methods and properties at the end of the interface file; don't add it to the middle.  Otherwise it will throw off the id's that are assigned to parameters and such and you'll get unexpected errors.
    Thursday, April 12, 2018 9:10 PM