.NET客户端在用与其版本相同的新dll替换已注册的COM dll时崩溃

8
我们有一个旧的C/C++ .dll,已经进行了COM注册。我们的客户端有本地和.NET客户端,都使用这个.dll。
我们建立了一个新的.NET .dll来替换旧的.dll,即它们的COM接口是相同的。我们希望在不需要客户端重新编译或做任何事情的情况下替换旧的.dll。
对于本地客户端,只需注销旧的.dll并注册新的.dll(使用regasm)即可正常工作。对于一些.NET客户端也适用。然而,在这些情况下,当客户端和新的.dll都使用相同的.NET版本编译时,会抛出以下异常。
换句话说,以下内容是有效的:
.dll is .NET 3.5 -> client is .NET 4.0
.dll is .NET 4.0 -> client is .NET 3.5
.dll is any .NET -> Client is native

这会抛出以下异常:
.dll is .NET 4.0 -> client is .NET 4.0
.dll is .NET 3.5 -> client is .NET 3.5

[A]BARAPIXLib.barcom5无法转换为[B]BARAPIXLib.barcom5。 类型A源自'BARAPIXLib,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null',位于位置C:\arkiv\S_BTW\BTW\BARAPIXWebService\Barapix\bin\BARAPIXLib.dll的上下文'LoadFrom'中。 类型B源自'BartrackTest,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null',位于位置'C:\arkiv\Bartrack\BartrackTest\x86\Src\BartrackTest\bin\x86\Release\BartrackTest.exe'的上下文'Default'中。如果您有任何想法,请告诉我。

有没有可能让我们看到DLL方法引用的声明以及一些调用代码? - pickypg
你是指客户如何调用我们的.dll文件吗?这对我们来说是未知的,但他们可能已经在Visual Studio中执行了“添加引用”的操作。我们希望用一个新的.NET文件替换旧的C/C++ COM .dll文件,而不需要重新编译或做任何其他事情。如果这是可能的话。 - Poppert
2个回答

1

尝试注销任何先前的版本,并检查dll文件是否与可执行文件位于同一文件夹中。还要尝试查看您从哪里加载dll文件。我认为您是手动加载它,因此请查看您引用错误dll文件的地址。


感谢您的回复!我们注销了旧的 C/C++ .dll 文件,将文件替换为新的 .NET 文件(使用相同的文件名并放置在同一目录中),并使用 regasm 注册它。但是客户端仍然不起作用(无需重新编译等)。基本上,它显示“无法将 SomeTypeA 转换为 SomeTypeAClass”(“Class” 在类型名称中被添加)。 - Poppert

1
这可能是因为在使用相同版本的 .net framework 的情况下,返回给客户端的实例不再是 COM 包装器,而是纯 .Net 对象,因此当您尝试将其强制转换为 COM 接口时会失败。 这里有一个类似的问题 here。解决方案涉及使用 Primary Interop Assembly

谢谢您的回复! 我们的客户已经对我们旧的C/C++ COM .dll进行了“添加引用”,所以在客户端目录中有一个客户端.exe使用的"Interop.blablabla.dll"。我们能否强制我们的客户端使用新的主互操作程序集,而不是他们已经在使用的那个(而无需重新编译等)? - Poppert
@Poppert,恐怕这是不可能的。据我所知,PIA 可能会有不同的类型名称。无论如何,发表一个新的 SO 问题来专门讨论这个话题可能是个好主意,你可能会得到一些创造性的解决方案。 - yms

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接