如果只有.NET 2.0 RTM,运行时如何解析对.NET 2.0 SP1程序集的调用

3
我们的应用程序是基于.NET 2.0构建的,安装了.NET 2.0 SP1。该应用程序引用了一些标准的.NET程序集,包括.NET SP1中的System.Xml.dll。
如果我们在安装了.NET 2.0 RTM的计算机上运行此应用程序,则该应用程序可以正常运行,甚至使用System.Xml.dll程序集。但是,当它尝试使用在2.0 RTM中不存在但在2.0 SP1中存在的方法时,该应用程序会抛出MethodNotFoundException异常。
我的问题是:运行时如何解析System.Xml.dll?
程序集版本的修订号不同(但主要、次要和构建部分相等)。这意味着2.0 RTM和2.0 SP1程序集在程序集绑定过程方面是不同的。运行时应该尝试查找System.Xml.dll 2.0.50727.1378,但它只能找到2.0.50727.42。然后程序集绑定过程应该失败,因为Machine.config中不能有任何发布者策略或重定向。但是绑定却可以正常工作。这是怎么回事?
另一个问题是根据上述描述的问题。我们无法强制所有客户端在其计算机上安装.NET 2.0 SP1。如果我们从.NET 2.0 SP1中提取System.Xml.dll,我们如何强制我们的应用程序使用随应用程序一起提供的System.Xml.dll?
更新1:看起来System.Xml.dll版本是2.0.0.0,而不是2.0.50727.x。这解释了为什么运行时可以成功解析它。但第二个问题仍然适用:我们可以从SP1中提取System.Xml.dll,并强制我们的应用程序使用它吗?

客户使用2.0 RTM版本的问题已经出现了一段时间。我们必须选择是否只使用2.0 RTM功能重写应用程序,或者我们可以修复一些运送2.0 SP1组件的东西。现在问题只存在于System.Xml.dll,看起来从SP1发货组件比重写我们的应用程序要容易得多。 - Dmitrii Lobanov
2个回答

1

如果没有可接受的答案,我会发布自己的。希望能帮到某些人。

第一个问题是运行时如何从服务包中解析程序集。

我进行了一些调查并阅读了一些文章。我错误地查看了AssemblyFileVersion而不是AssemblyVersion。对于.NET 2.0 SP中的程序集,AssemblyFileVersion2.0.50727.1378,而对于来自.NET 2.0 RTM的程序集,则为2.0.50727.42。是的,它们是不同的,但这是AssemblyFileVersion,而不是AssemblyVersion。程序集绑定过程仅使用AssemblyVersion。但是,.NET 2.0 RTM.NET SPxAssemblyVersion均为2.0.0.0。因此,在程序集绑定过程方面,RTMSPx程序集是相同的。

我还很感兴趣为什么微软没有随着增加的 AssemblyVersion 发布服务包的程序集?他们可以发布带有相应发布者策略的 SP 程序集,以将程序集绑定从 RTM 重定向到 SP。如果客户想要使用程序集的 RTM 版本,则可以忽略特定程序集的发布者策略。实际上,我认为微软拒绝这样做是因为如果客户开始忽略某些程序集的发布者策略而不忽略其他程序集的话,那就会变成一团糟。那么 BCL 的程序集就不能互相依赖,整个 BCL 就会变得不一致。

第二个问题是关于是否可能将 .NET 2.0 SP1 程序集与我们的产品一起发布,并将程序集绑定从 RTM 程序集重定向到 SP 程序集。

简短的回答是“不可能”。但有两种可能的解决方案,但它们非常糟糕,只能在严格的情况下使用,在一般情况下根本不适用。

第一种解决方案是反汇编CLR程序集,然后再使用我们的公钥重新构建它,或者完全省略强名称签名。现在我们将能够从GAC引用这个RTM程序集而不是SP's程序集。

第二种解决方案是使用gacutil工具用SP的程序集替换GAC中的RTM程序集。必须使用/f(强制)选项。

这两种解决方案都非常糟糕。请不要使用它们。通常由于程序集之间的某些依赖关系,它们不能被使用。

结论

在我们的产品中,我们降级了产品,以便它可以在.NET 2.0 RTM上运行。但是我们仍然使用一些来自.NET 3.x的功能(如linq-to-objectsActionFunc)。我们只是将一些3.x程序集与我们的产品一起发布,例如System.Core.dll。大多数情况下,我们没有遇到问题。但是我们也不得不放弃使用Linq-to-Xml,因为存在一些无法解决的问题。


0

.NET 版本仅对强名称程序集强制执行。

您不能(也不应该)期望在使用 SP1 编译时以 RTM 版本运行的程序能够正确运行。它可能会正常运行,但也可能以神秘的方式失败。


System.Xml.dll 是一个强名称程序集,它驻留在全局程序集缓存中。 - Dmitrii Lobanov
标准程序集并非完全相同。我认为您必须选择使用强名称。否则,如果所有.NET标准程序集的版本都固定,当您使用RTM编译程序时,它可能无法在安装了SP1、SP2或SP3的计算机上运行。 - Stephen Chung
1
好的,针对这种情况,有一种叫做“发布者策略”的东西,当微软发布服务包时,可以将重定向添加到新的程序集中。我想这就是“发布者策略”旨在解决的问题。 - Dmitrii Lobanov

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