2013-07-11 26 views
1

这个问题是this question的续篇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#程序使用任何COM/C++ DLL版本1.2.anything。

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

回答

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-interop-dll不必注册COM。你可以安装这个程序集很多次你喜欢。但它需要你的COM-DLL注册COM。

有用的工具:

  • TLBIMP
  • regasm
  • SN
3

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

这是相当不可能的在实践中工作,搞乱DLL地狱当你使用COM是非常不明智的。如果您使用早期绑定,则COM无法验证您是否正在调用正确的方法。与.NET不同的是,抖动可以在运行时根据程序集中的元数据进行检查。如果C++程序员做对了,那么他改变了他改变的类型的指导。这将使你的代码被E_NOINTERFACE炸弹,因为你将使用旧版本的GUID。

如果他不这样做,不幸的是,这种方式太常见了,那么你的程序很可能会碰到一些像AccessViolationException这样令人讨厌的东西。或者更糟糕的是,它不会崩溃,但会调用完全错误的方法。

失效模式更良性,当您使用后期绑定,你会得到当方法不存在,或者如果它的参数已经改变了IDispatch错误之一。并不是说这最终解决了任何问题,你仍然有一个不起作用的程序。只有当你喜欢危险地生活时,才会像这样混淆DLL地狱。