这个问题是this question
的续集我们正在创建一个用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#项目中配置它?
答案 0 :(得分:3)
我建议你不要直接引用你的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。
有用的工具:
答案 1 :(得分:3)
在我之前的问题中记录它的方式没有什么不同。您仍然使用<bindingRedirect>
来加载错误版本的互操作程序集。
在实践中工作的可能性相当大,在使用COM时弄乱DLL Hell是非常不明智的。如果您使用早期绑定,则COM无法验证您是否正在调用正确的方法。与.NET非常不同,抖动可以在运行时通过程序集中的元数据进行类似的检查。如果C ++程序员做得对,那么他就改变了他改变的类型的指南。因为你将使用旧版本的guid,这将使你的代码炸弹与E_NOINTERFACE。
如果他没有,不幸的是太常见了,那么你的程序很容易崩溃,就像AccessViolationException一样令人讨厌。或者更糟糕的是,它不会崩溃,但会调用完全错误的方法。
当您使用后期绑定时,失败模式更为温和,当方法不存在或其参数发生更改时,您将获得IDispatch错误之一。并不是说这最终解决了任何问题,你仍然有一个不起作用的程序。只有当你喜欢危险地生活时,才能与DLL混乱。