【问题标题】:Calling an old OLE component from C#从 C# 调用旧的 OLE 组件
【发布时间】:2010-08-23 16:52:55
【问题描述】:

我有一个非常旧的 (VC++ 5.0) 专有 DLL,我需要从 C# (Visual Studio 2010) 使用它。该示例指定要访问此组件,我需要调用CreateDispatch("application"),这表示指向 OLE。

以下是示例代码(C++):

IComponentServer Server;
Server.CreateDispatch("Component.Server");

我通过 Visual Studio 向我拥有的 TLB 文件添加了一个引用,我可以成功导入其命名空间,但 IComponentServer 没有任何名为 CreateDispatch 的方法。

通过 C# 创建 OLE 组件实例的正确方法是什么?

【问题讨论】:

    标签: c# dll ole typelib


    【解决方案1】:

    如果您有 CLSID 或 ProgID,则可以使用以下一组方法。

    var type = Type.GetTypeFromProgID(progIdString);
    var obj = Activator.CreateInstance(type);
    var server = (IComponentServer)obj;
    

    【讨论】:

    • 感谢 JaredPar。知道为什么我可能会使用您提供的代码获得 InvalidCastException 吗?此操作失败,因为 IID 为“{BAA135B2-F931-11D0-9C14-0060973155F0}”的接口的 COM 组件上的 QueryInterface 调用因以下错误而失败:不支持此类接口(来自 HRESULT 的异常:0x80004002 (E_NOINTERFACE)) .
    • @jbx,最可能的原因是 COM 程序集的类型库没有正确注册。
    • 我试过 regasm 失败了,它说它不是一个有效的 .Net 程序集(没错,这是一个 VC++ 5.0 时代的旧库)我试过 regtlibv12.exe,它说它注册了TLB 成功。然而同样的问题。有什么想法我能做什么?
    【解决方案2】:

    MFC 的CreateDispatch 基于 CLSID 或 ProgId 字符串创建 COM 对象。您可以直接从 C# 代码实例化 COM 对象。

    假设 Visual Studio 参考为您提供 Interop.Component.dll

    IComponentServer server = new Interop.Component.ServerClass();
    

    【讨论】:

    • 可能无法正常工作,MFC 代码使用的是后期绑定的 IDispatch 接口。除非 OP 使用 4.0 版并且可以利用 dynamic,否则在 C# 中做到这一点并不容易。一个用 VB.NET 编写的小适配器是一种选择。
    • 这可能是唯一的选择 - 根据@JaredPar 的回答,类型库看起来不太好。
    • 你能解释一下 Interop 包是从哪里来的吗?在这里有点迷失了。
    • @jbx Visual Studio 在您添加 TLB 引用时生成它。您可以导入其命名空间这一事实表明互操作性很好。但是,您的 InvalidCastException 表明 TLB 本身并不可靠。
    • 谢谢,现在我明白你的意思了。实际上,您不能真正(至少在我的情况下)直接实例化 ServerClass(它说不能嵌入 Interop 类型,请使用适用的接口)。但是接口 IComponentServer 有一个 [CoClass] 属性,它引用要实例化的 COM 类。因此,通过一些调整,您的建议应该会奏效。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多