C#程序如何使用任何版本的COM dll?

这个问题是这个问题的续集

我们正在创建一个用C ++编写的DLL,提供对某些硬件的访问。 这个DLL实现并使用COM接口访问。 我们还有一个C#程序,它通过COM对象使用这个dll。

我们遇到了版本问题。 实际上,在运行C#程序时,它绝对想要使用编译时使用的精确COM / C ++ DLL版本。 即如果C#程序是使用COM / C ++ dll 1.2.3.4编译的,那么程序将拒绝使用COM / C ++ dll 1.2.3.5运行。

Unhandled Exception: System.TypeInitializationException: The type initializer for 'MyDllVerify.App' threw an exception. ---> System.IO.FileNotFoundException: Could not load file or assembly 'MyCorp.MyDll.Interop, Version=1.2.3.4, Culture =neutral, PublicKeyToken=ced78d295d1e0f2b' or one of its dependencies. The system cannot find the file specified. File name: 'MyCorp.MyDll.Interop, Version=1.2.3.4, Culture=neutral, PublicKey Token=ced78d295d1e0f2b' at MyDllVerify.App..cctor() 

我想指示C#程序使用任何版本为1.2的COM / C ++ DLL。

我在哪里可以在C#项目中配置它?

我建议你不要直接引用你的C#项目中的COM-dll。 如果这样做,在构建时总会生成一个新的COM-interop-dll。 这可能会导致很多问题。

创建COM-interop-dll,将其存储在库文件夹中并在C#项目中引用此库是一种更好的方法。 保持此COM-interop-dll尽可能静态。 如果你这样做,你可以根据需要更换用过的COM-dll,只要你的接口没有改变。

您可以尝试操作此互操作程序集并对1.2。*进行版本检查,如果您真的想要它(我不建议这样做,它可能会导致严重的混淆)。

说明:COM-interop-dll是常规的.NET程序集。 它的工作方式类似于C#代码和COM-C ++之间的包装 – 您希望在C#代码中使用的代码。

COM-interop-dll不必为COM注册。 您可以多次安装此程序集。 但它要求您的COM-dll已注册COM。

有用的工具:

  • TLBIMP
  • regasm
  • SN

在我之前的问题中记录它的方式没有什么不同。 您仍然使用来允许加载错误版本的互操作程序集。

它实际上不太可能在实践中工作,当你使用COM时弄乱DLL Hell是非常不明智的。 如果您使用早期绑定,则COM无法validation您是否正在调用正确的方法。 与.NET非常不同,抖动可以在运行时通过程序集中的元数据进行类似的检查。 如果C ++程序员做得对,那么他就改变了他改变的类型的指南。 因为你将使用旧版本的guid,这将使你的代码炸弹与E_NOINTERFACE。

如果他没有,不幸的是太常见了,那么你的程序很容易崩溃,就像AccessViolationException一样令人讨厌。 或者更糟糕的是,它不会崩溃,但会调用完全错误的方法。

使用后期绑定时,失败模式更加良性,当方法不存在或其参数发生更改时,您将获得IDispatch错误之一。 并不是说这最终解决了任何问题,你仍然有一个不起作用的程序。 只有当你喜欢生活危险时,才能与DLL混乱。