尝试在C#中构建一个可以从VB5 / 6引用和使用的COM组件

时间:2011-04-27 21:58:52

标签: c# .net com-interop

我试图看看我是否可以在C#(.NET 4)中构建一个COM组件,我可以从VB5程序(提示嘲讽性评论)中使用它来访问Web服务。按照以下所有说明,我可以在MSDN和CodeProject上找到如下:

我写了以下内容:

[Guid("7A715F02-D349-45DC-B0AE-9925FD3B943C")]
public interface ARCOM_Interface
{
    [DispId(1)]
    string GetServiceResponse();
}

[Guid("5130F041-619E-41F9-84B6-8332642228F6")
    , InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface ARCOM_Events
{
}

[Guid("0A77754F-34CF-4E0E-AAC2-85FD686758E0")
    , ClassInterface(ClassInterfaceType.None)
    , ComSourceInterfaces(typeof(ARCOM_Events))]
[ComVisible(true)]
public class ARCOM_Class : ARCOM_Interface
{
    public string GetServiceResponse()
    {
        string response = string.Empty;

        ARWebService.ARWebService svc = new ARWebService.ARWebService();

        response = svc.PingMeBack();

        return response;
    }
}

有问题的大会以强名称签名,输出已注册COM Interop。构建之后,我已经将RegAsm应用于它并使用tlbexp.exe生成了一个类型库。

在VB6中,当我从Project属性中打开引用列表时,我可以在列表中找到程序集,我可以检查它。我甚至可以在VB6代码中执行以下操作:

Private Sub HitWebService()

    Dim arcom As ARCOMObject.ARCOM_Class

    arcom. <== Intellisense doesn't sense anything!

End Sub

Intellisense看到ARCOMObject和类,但ARCOM_Class本身内没有任何内容(除了通常的“GetType”,“Equals”和其他通用Object方法/属性)。最具体地说,它似乎没有看到GetServiceResponse()方法,所以我无法调用它。

我要离开的是什么?

2 个答案:

答案 0 :(得分:2)

好的,我发现了一些意想不到的东西。

请注意,上面的代码包含装饰[ComVisible(true)]。使组件对COM可见当然是必不可少的。我认为这涵盖了它,但经过进一步搜索,我发现还有另一个地方可以标记它。如果查看项目属性,则在“应用程序”选项卡中,您将找到“装配信息...”按钮。单击它,在对话框的底部,您将看到一个复选框“Make assembly COM-visible”。我检查了一下,重新编译(并重新运行tlbexp和regasm),然后发现方法GetServiceResponse()是可见的。

我不知道为什么make ComVisible复选框在设置属性时不起作用。

编辑添加:我想我知道这是怎么回事。 ComVisible(true)使类对COM可见,但不对程序集可见;这就是为什么需要检查“Make assembly COM-visible”,因为GetServiceResponse方法似乎通过ARCOM_Interface获得COM可见性,除非程序集也是如此,否则它不会被标记为ComVisible。

答案 1 :(得分:2)

我看到你在输入这个回复时找到了想要得到你想要的东西的方法,但我还是会继续,因为它可能会告诉你一些你不知道的东西......

您已将ClassInterface(ClassInterfaceType.None)属性应用于该类。这告诉COM互操作不要为类定义显式接口,因此您的客户端必须使用IDispatch(后期绑定)。这意味着您的客户端必须具有该类实现的接口的先验知识。也就是说,您(程序员)知道可用的方法,但IntelliSense等工具无法找到该信息。

请继续调用方法:

Dim response As String
response = arcom.GetServiceResponse