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

发布于 2024-10-24 22:08:43 字数 867 浏览 4 评论 0原文

我们在安装了 .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 中不能有任何发布者策略或重定向。但绑定效果很好。怎么可能呢?

上述问题的另一个问题。

我们无法强制所有客户在其计算机上安装 .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 与我们的应用程序一起提供并强制我们的应用程序使用它吗?

We have application built against .NET 2.0 on machine with .NET 2.0 SP1 installed. The application references some standard .NET assemblies included in .NET SP1 (i.e. System.Xml.dll).

If we run this application on computer with .net 2.0 RTM, the application runs fine, it even uses System.Xml.dll assembly. But when it tries to use method that doesn't exist in 2.0 RTM, but exists in 2.0 SP1 the application throws MethodNotFoundException.

My question is : How does the runtime resolve System.Xml.dll at all?

The assemblies versions differs in revision number (but the major, minor and build parts are equals). That means that 2.0 RTM and 2.0 SP1 assemblies are different in terms of assembly binding process. The runtime should try to find System.Xml.dll 2.0.50727.1378, but it only finds 2.0.50727.42. Then assembly binding process should fail because there can't be any Publisher policy or redirection in Machine.config. But binding works fine. How can it be?

Another one question which follows of the problem described above.

We can't force all our clients to install .NET 2.0 SP1 on their computers. If we ship System.Xml.dll from .NET 2.0 SP1, how can we force our application to use System.Xml.dll shipped with our application?

Update 1: Looks like System.Xml.dll version is 2.0.0.0, not 2.0.50727.x. That describes why the Runtime successfully resolves it. But the second question still applies: Can we ship System.Xml.dll from SP1 with our application and force our application to use it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

沉鱼一梦 2024-10-31 22:08:43

如果没有可接受的答案,我将发布我自己的答案。希望它对某人有帮助。

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

我已经进行了更多研究并阅读了一些文章。我错误地查看了 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 SPx 来说,AssemblyVersion2.0.0.0。因此,RTMSPx 程序集在程序集绑定过程方面是相同的。

我仍然感兴趣为什么 MS 没有提供带有增量 AssemblyVersion 的服务包程序集?他们可以使用相应的发布者策略来运送 SP 程序集,以将程序集绑定从 RTM 重定向到 SP。如果客户想要使用 RTM 版本的程序集,他们可以忽略特定程序集的发布者策略。实际上,我认为微软拒绝走这条路,因为如果客户端开始忽略某些程序集的发布者策略而不忽略其他程序集,那将是一团糟。由于 BCL 程序集无法相互依赖,整个 BCL 将变得不一致。

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

简短的回答是“不,这是不可能的”。但有两种可能的解决方案,但它们都很蹩脚,只有在严格的情况下才能使用,一般来说它们根本不适用。

第一个解决方案是解除 CLR 程序集,然后使用我们的公钥再次构建它,或者我们可以完全省略强签名。现在,我们将能够引用此 RTM 程序集,而不是来自 GAC 的 SP 程序集。

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

这两种解决方案都非常蹩脚。请不要使用它们。一般来说,由于程序集之间存在某些依赖性,它们无法使用。

结论

在我们的产品中,我们降级了产品,使其可以在 .NET 2.0 RTM 上运行。但我们仍然使用 .NET 3.x 中的一些功能(linq-to-objectsActionFunc >)。我们只是随产品一起提供一些 3.x 程序集,例如 System.Core.dll。大多数情况下,我们对这种方法没有任何问题。但由于一些无法解决的问题,我们也不得不拒绝使用 Linq-to-Xml

If there is no acceptable answers I'll post my own. Hope it helps somebody.

The first question was how does runtime resolves assemblies from service pack.

I've investigated a little more and have read some articles. I mistakenly have taken a look at AssemblyFileVersion instead of AssemblyVersion. For assemblies in .NET 2.0 SP AssemblyFileVersion is 2.0.50727.1378, and for assemblies from .NET 2.0 RTM it's 2.0.50727.42. Yes, they are different, but it is AssemblyFileVersion, not AssemblyVersion. And assembly binding process uses AssemblyVersion only. But AssemblyVersion is 2.0.0.0 for .NET 2.0 RTM and .NET SPx either. So RTM and SPx assemblies are identical in terms of assembly binding process.

I'm still interested why MS hadn't shipped service pack's assemblies with incremented AssemblyVersion? They could ship SP's assemblies with corresponding Publisher policies to redirect assembly binding from RTM to SP. And if clients would like to use RTM versions of assemblies, they can ignore publisher policy for particular assemblies. Actually, I think that MS refused to go that way because it would be a total mess if client start to ignore publisher policies on some assemblies and don't ignore on others. Than BCL's assemblies couldn't rely on each other, the whole BCL would become inconsistent.

The second question was about the possibility to ship .NET 2.0 SP1 assemblies with our product and to redirect assembly binding from RTM assembly to SP's assembly.

The short answer is "no, it is not possible". But there are 2 possible solutions, but they are quite lame and can be of use only under strict circumstances and in general they are not applicable at all.

The first solution is to disasm CLR assembly and then build it again but with our public key, or we can omit strong-signing at all. Now we will be able to reference this RTM assembly rather than SP's assembly from GAC.

The second solution is to replace RTM's assembly in GAC with SP's assembly using the gacutil tool. The /f (force) option must be used.

Both of these two solutions are very lame. Please, don't use them. In general they can't be used due to some dependencies between assemblies.

Conclusion

In our product we downgraded our product so it could work on .NET 2.0 RTM. But we still use some functionality even from .NET 3.x (linq-to-objects, Action, Func). We just ship some of the 3.x assemblies with our product, e.g. System.Core.dll. Mostly we have no problems with this approach. But we also had to decline using Linq-to-Xml because of some unsolvable problems.

§普罗旺斯的薰衣草 2024-10-31 22:08:43

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

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

.NET versionings are only enforced for strong-named assemblies.

You cannot (and should not) expect a program to run correctly on RTM version when it is compiled using SP1. It may run correctly, but it may also fail in mysterious ways.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文