我们在安装了.NET 2.0 SP1的机器上安装了针对.NET 2.0的应用程序。该应用程序引用了.NET SP1中包含的一些标准.NET程序集(即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中不能有任何Publisher策略或重定向。但绑定工作正常。怎么会这样?
上述问题的另一个问题。
我们无法强制所有客户在其计算机上安装.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并强制我们的应用程序使用它吗?
答案 0 :(得分:1)
如果没有可接受的答案,我会张贴自己的答案。希望它对某人有所帮助。
第一个问题是运行时如何解析Service Pack中的程序集。
我已经调查了一些,并阅读了一些文章。我错误地看了AssemblyFileVersion
而不是AssemblyVersion
。对于.NET 2.0 SP
AssemblyFileVersion
中的程序集2.0.50727.1378
,以及来自.NET 2.0 RTM
的程序集2.0.50727.42
。是的,它们不同,但它是AssemblyFileVersion
,而不是AssemblyVersion
。汇编绑定过程仅使用AssemblyVersion
。但AssemblyVersion
2.0.0.0
和.NET 2.0 RTM
.NET SPx
也是RTM
。因此SPx
和AssemblyVersion
程序集在程序集绑定过程方面是相同的。
我仍然感兴趣为什么MS没有提供增加SP's
的Service Pack程序集?他们可以使用相应的发布商政策发送RTM
程序集,以将程序集绑定从SP
重定向到RTM
。如果客户希望使用BCL's
版本的程序集,则可以忽略特定程序集的发布者策略。实际上,我认为MS拒绝采用这种方式,因为如果客户开始忽略某些程序集上的发布者策略而不忽视其他程序集,那将是一团糟。比BCL
集合不能相互依赖,整个.NET 2.0 SP1
会变得不一致。
第二个问题是关于是否可以将RTM
程序集与我们的产品一起发送,并将程序集绑定从SP's
程序集重定向到RTM
程序集。
简短的回答是“不,这是不可能的”。但是有两种可能的解决方案,但它们非常蹩脚,只能在严格的情况下才能使用,一般来说它们根本不适用。
第一个解决方案是解除CLR程序集然后使用我们的公钥再次构建它,或者我们可以省略强签名。现在,我们将能够从GAC引用此SP's
程序集而不是RTM's
程序集。
第二种解决方案是使用gacutil
工具将SP中的/f
程序集替换为SP的程序集。必须使用.NET 2.0 RTM
(强制)选项。
这两种解决方案都非常蹩脚。请不要使用它们。通常,由于程序集之间存在某些依赖关系,因此无法使用它们。
<强>结论强>
在我们的产品中,我们降级了我们的产品,因此它可以在.NET 3.x
上运行。但我们仍然使用linq-to-objects
(Action
,Func
,System.Core.dll
)的某些功能。我们只是用我们的产品运送一些3.x组件,例如Linq-to-Xml
。大多数情况下,我们对此方法没有任何问题。但是由于一些无法解决的问题,我们也不得不拒绝使用{{1}}。
答案 1 :(得分:0)
仅对强名称程序集强制执行.NET版本。
使用SP1编译时,您不能(也不应该)期望程序在RTM版本上正确运行。它可能正常运行,但它也可能以神秘的方式失败。