.NET 4.0 有一个新的 GAC,为什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2660355/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 14:11:01  来源:igfitidea点击:

.NET 4.0 has a new GAC, why?

.net.net-4.0gac

提问by Max Toro

%windir%\Microsoft.NET\assembly\is the new GAC. Does it mean now we have to manage two GACs, one for .NET 2.0-3.5 applications and the other for .NET 4.0 applications?

%windir%\Microsoft.NET\assembly\是新的GAC。这是否意味着现在我们必须管理两个 GAC,一个用于 .NET 2.0-3.5 应用程序,另一个用于 .NET 4.0 应用程序?

The question is, why?

问题是,为什么?

采纳答案by Brian R. Bondy

Yes since there are 2 distinct Global Assembly Cache (GAC), you will have to manage each of them individually.

是的,因为有 2 个不同的全局程序集缓存 (GAC),您必须单独管理它们中的每一个。

In .NET Framework 4.0, the GAC went through a few changes. The GAC was split into two, one for each CLR.

The CLR version used for both .NET Framework 2.0 and .NET Framework 3.5 is CLR 2.0. There was no need in the previous two framework releases to split GAC. The problem of breaking older applications in Net Framework 4.0.

To avoid issues between CLR 2.0 and CLR 4.0 , the GAC is now split into private GAC's for each runtime.The main change is that CLR v2.0 applications now cannot see CLR v4.0 assemblies in the GAC.

在 .NET Framework 4.0 中,GAC 经历了一些更改。GAC 一分为二,每个 CLR 一个。

用于 .NET Framework 2.0 和 .NET Framework 3.5 的 CLR 版本是 CLR 2.0。在前两个框架​​版本中没有必要拆分 GAC。在 Net Framework 4.0 中破坏旧应用程序的问题。

为了避免 CLR 2.0 和 CLR 4.0 之间的问题,现在 GAC 被拆分为每个运行时的私有 GAC。主要变化是 CLR v2.0 应用程序现在无法在 GAC 中看到 CLR v4.0 程序集。

Source

来源

Why?

为什么?

It seems to be because there was a CLR change in .NET 4.0 but not in 2.0 to 3.5. The same thing happened with 1.1 to 2.0 CLR. It seems that the GAC has the ability to store different versions of assemblies as long as they are from the same CLR. They do not want to break old applications.

似乎是因为 .NET 4.0 中有 CLR 更改,但 2.0 到 3.5 中没有。1.1 到 2.0 CLR 也发生了同样的事情。似乎 GAC 有能力存储不同版本的程序集,只要它们来自同一个 CLR。他们不想破坏旧的应用程序。

See the following information in MSDN about the GAC changes in 4.0.

请参阅MSDN 中有关 4.0 中 GAC 更改的以下信息。

For example, if both .NET 1.1 and .NET 2.0 shared the same GAC, then a .NET 1.1 application, loading an assembly from this shared GAC, could get .NET 2.0 assemblies, thereby breaking the .NET 1.1 application

The CLR version used for both .NET Framework 2.0 and .NET Framework 3.5 is CLR 2.0. As a result of this, there was no need in the previous two framework releases to split the GAC. The problem of breaking older (in this case, .NET 2.0) applications resurfaces in Net Framework 4.0 at which point CLR 4.0 released. Hence, to avoid interference issues between CLR 2.0 and CLR 4.0, the GAC is now split into private GACs for each runtime.

例如,如果 .NET 1.1 和 .NET 2.0 共享相同的 GAC,那么从这个共享的 GAC 加载程序集的 .NET 1.1 应用程序可以获得 .NET 2.0 程序集,从而破坏 .NET 1.1 应用程序

用于 .NET Framework 2.0 和 .NET Framework 3.5 的 CLR 版本是 CLR 2.0。因此,在前两个框架​​版本中无需拆分 GAC。在 CLR 4.0 发布时,Net Framework 4.0 中再次出现了破坏旧(在本例中为 .NET 2.0)应用程序的问题。因此,为了避免 CLR 2.0 和 CLR 4.0 之间的干扰问题,现在将 GAC 拆分为每个运行时的私有 GAC。

As the CLR is updated in future versions you can expect the same thing. If only the language changes then you can use the same GAC.

随着 CLR 在未来版本中更新,您可以期待同样的事情。如果仅更改语言,则您可以使用相同的 GAC。

回答by Jasl

I also wanted to know why 2 GAC and found the following explanation by Mark Millerin the comments sectionof .NET 4.0 has 2 Global Assembly Cache (GAC):

我也想知道为什么2 GAC,发现如下马克·米勒解释评论部分.NET 4.0有2全局程序集缓存(GAC)

Mark Miller said...June 28, 2010 12:13 PM

Thanks for the post. "Interference issues" was intentionally vague. At the time of writing, the issues were still being investigated, but it was clear there were several broken scenarios.

For instance, some applications use Assemby.LoadWithPartialName to load the highest version of an assembly. If the highest version was compiled with v4, then a v2 (3.0 or 3.5) app could not load it, and the app would crash, even if there were a version that would have worked. Originally, we partitioned the GAC under it's original location, but that caused some problems with windows upgrade scenarios. Both of these involved code that had already shipped, so we moved our (version-partitioned GAC to another place.

This shouldn't have any impact to most applications, and doesn't add any maintenance burden. Both locations should only be accessed or modified using the native GAC APIs, which deal with the partitioning as expected. The places where this does surface are through APIs that expose the paths of the GAC such as GetCachePath, or examining the path of mscorlib loaded into managed code.

It's worth noting that we modified GAC locations when we released v2 as well when we introduced architecture as part of the assembly identity. Those added GAC_MSIL, GAC_32, and GAC_64, although all still under %windir%\assembly. Unfortunately, that wasn't an option for this release.

马克·米勒说... 2010 年 6 月 28 日下午 12:13

谢谢你的帖子。“干扰问题”是故意含糊的。在撰写本文时,这些问题仍在调查中,但很明显有几个破碎的场景。

例如,某些应用程序使用 Assemby.LoadWithPartialName 加载程序集的最高版本。如果最高版本是使用 v4 编译的,那么 v2(3.0 或 3.5)应用程序将无法加载它,即使有一个可以运行的版本,该应用程序也会崩溃。本来我们把GAC分区到了原来的位置,但是这导致了windows升级场景的一些问题。这两个都涉及已经发布的代码,因此我们将(版本分区的 GAC)移到了另一个地方。

这应该不会对大多数应用程序产生任何影响,并且不会增加任何维护负担。这两个位置只能使用本机 GAC API 访问或修改,它们按预期处理分区。出现这种情况的地方是通过 API 公开 GAC 的路径,例如 GetCachePath,或检查加载到托管代码中的 mscorlib 的路径。

值得注意的是,我们在发布 v2 时以及在引入架构作为程序集标识的一部分时修改了 GAC 位置。那些添加了 GAC_MSIL、GAC_32 和 GAC_64,尽管它们仍然在 %windir%\assembly 下。不幸的是,这不是此版本的选项。

Hope it helps future readers.

希望对未来的读者有所帮助。

回答by Hans Passant

It doesn't make a lot of sense, the original GAC was already quite capable of storing different versions of assemblies. And there's little reason to assume a program will ever accidentally reference the wrong assembly, all the .NET 4 assemblies got the [AssemblyVersion] bumped up to 4.0.0.0. The new in-process side-by-side feature should not change this.

这没有多大意义,原始的 GAC 已经能够存储不同版本的程序集。并且几乎没有理由假设程序会意外引用错误的程序集,所有 .NET 4 程序集的 [AssemblyVersion] 都提高到了 4.0.0.0。新的进程内并行功能不应改变这一点。

My guess: there were already too many .NET projects out there that broke the "never reference anything in the GAC directly" rule. I've seen it done on this site several times.

我的猜测:已经有太多的 .NET 项目打破了“永远不要直接引用 GAC 中的任何内容”规则。我已经在这个网站上看到它做过好几次了。

Only one way to avoid breaking those projects: move the GAC. Back-compat is sacred at Microsoft.

只有一种方法可以避免破坏这些项目:移动 GAC。反向兼容性在微软是神圣的。