从 C# 引用不同的 ActiveX 版本作为一个
Posted
技术标签:
【中文标题】从 C# 引用不同的 ActiveX 版本作为一个【英文标题】:Referencing different ActiveX versions from C# as one 【发布时间】:2021-05-31 01:14:16 【问题描述】:我在尝试接下来的事情时非常挣扎。
我目前正在使用 ActiveX,通过 Visual Studio 生成的互操作 dll(更准确地说是 tlbimp,隐式)。
存在此 ActiveX 的不同版本,有时会在接口中添加、删除属性。如果要改版本,就得改引用,重新编译等等。
我想要我的代码的单一版本。我记得以驱动 Word 为例,可以通过 Word.Application 上的 CreateInstance 实例化一个单词对象,并调用方法,无论版本如何。仅在运行时链接调用。我想对我使用的 activeX 做同样的事情,但我真的不知道该怎么做(顺便说一句,它是 sage objets100c dll)。我在 ActiveX 列表中找不到它,因此我什至不确定我是否可以为 Word.Application 做这样的事情。
有人知道我该怎么做吗? (可能是一个完全不同的解决方案,因为我的需要是:拥有一个无需重新编译的代码)。
提前谢谢你
【问题讨论】:
您可以使用 C#dynamic
关键字:docs.microsoft.com/en-us/dotnet/csharp/programming-guide/types/… 但如果您经常使用该库,可能会很痛苦。否则,您可以使用最低版本的 TLB 作为基础,仅在使用较新的属性/方法时使用动态。
@SimonMourier Merci Simon :) 我不能使用 tlb 作为基础,因为 v2(例如)向枚举添加了新值、接口中的新方法等等,(并且有人删除了他们)使他们不兼容。我找到了另一种方法,通过代码反映 interop dll 以使用动态对象生成一种中间层。如果可以的话,我很荣幸你回答了我的问题,我过去很多时间都在不同的个人项目中使用过你的 HAP 库,它非常有用。
【参考方案1】:
如果您有相应的 *.tlb 文件,请引用此文件,而不是 dll。在引用的属性窗口中,可以将Specific Version
属性设置为False
,将EmbedInterop Types
设置为True
(使其更稳定)。
如果这没有帮助,您可以尝试动态创建和访问对象,而不是添加引用。您需要 COM 类型的 ProgID
...
Type comType = Type.GetTypeFromProgID("MyProg.ProgId");
... 或 COM 类型的 CLSID(您可以在注册表中找到它们)
Type comType = Type.GetTypeFromCLSID(new Guid("EA2BACD6-9D0F-4819-98BC-88E8173D3D16"));
然后您可以使用Activator.CreateInstance
创建和对象并将其分配给dynamic
以进行后期绑定。
dynamic sage100 = Activator.CreateInstance(comType);
您将不会获得此 dynamic
对象的 IntelliSense。如果您指定不存在的成员(方法或属性名称),您仍然可以编译和运行您的 C# 代码;但是,当您尝试访问这些成员时,将引发运行时异常。
【讨论】:
嗨 Olivier,感谢您在此处列出的不同点。实际上,我的代码中有这些步骤,但无法将它们粘合在一起:通过反汇编互操作 dll 获得的 Guid 不适用于 GetTypeFromProgId,查看注册表给我的 Guid 不适用于 GetTypeFromCLSID。最终我找到了一个 ProgId,在论坛中使用 GetTypeFromProgId(列出注册的 ActiveX 并没有给我),并找到了一种在维护 Intellisense 的同时管理版本的方法。无论如何,我将您的答案标记为正确:)以上是关于从 C# 引用不同的 ActiveX 版本作为一个的主要内容,如果未能解决你的问题,请参考以下文章
如何从 C# 等托管代码中为 ActiveX 组件使用嵌入式免注册清单?