1

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

我们正在创建一个用 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.anything 的 COM/C++ dll。

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

4

2 回答 2

3

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

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

如果你真的想要,你可以尝试操纵这个互操作程序集并在那里检查 1.2.* 的版本(我不建议这样做,它可能会导致严重的混乱)。

说明: COM-interop-dll 是一个常规的 .NET 程序集。它就像你的 C# 代码和你想在 C# 代码中使用的 COM-C++ 代码之间的一个包装器。

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

有用的工具:

  • tlbimp
  • 再高潮
于 2013-07-11T14:20:45.197 回答
3

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

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

如果他不这样做,不幸的是太常见了,那么你的程序很可能会因为诸如 AccessViolationException 之类的讨厌的东西而崩溃。或者更糟的是,它不会崩溃,但会调用完全错误的方法。

当您使用后期绑定时,故障模式更为温和,当方法不存在或其参数已更改时,您将收到 IDispatch 错误之一。并不是说这最终会解决任何问题,您仍然有一个不起作用的程序。仅当您喜欢危险地生活时,才像这样弄乱 DLL Hell。

于 2013-07-11T14:36:51.713 回答