%windir%\Microsoft.NET\assembly\
是新的全局程序集缓存(GAC)。这是否意味着现在我们需要管理两个GAC,一个用于.NET 2.0-3.5应用程序,另一个用于.NET 4.0应用程序?
%windir%\Microsoft.NET\assembly\
是新的全局程序集缓存(GAC)。这是否意味着现在我们需要管理两个GAC,一个用于.NET 2.0-3.5应用程序,另一个用于.NET 4.0应用程序?
是的,由于存在两个不同的全局程序集缓存(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程序集。
为什么?
似乎是因为.NET 4.0中发生了CLR更改,而2.0到3.5没有。1.1到2.0 CLR也发生了同样的事情。GAC似乎具有存储不同版本程序集的能力,只要它们来自相同的CLR即可。他们不想破坏旧应用程序。
例如,如果.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。在Net Framework 4.0中,旧版(在本例中为.NET 2.0)应用程序被破坏的问题再次出现,此时CLR 4.0发布。因此,为避免CLR 2.0和CLR 4.0之间的干扰问题,现在将GAC分成每个运行时的私有GAC。随着CLR在未来版本中的更新,您可以期望相同的事情发生。如果只更改语言,则可以使用相同的GAC。我也想知道为什么有两个全局程序集缓存(GAC),在.NET 4.0 has 2 Global Assembly Cache (GAC)的评论区中,Mark Miller给出了以下解释:
希望能帮助未来的读者。Mark Miller说... 2010年6月28日下午12:13
感谢您的文章。"干扰问题"是有意模糊的。在写作时,这些问题仍在调查中,但很明显存在几个破碎的场景。
例如,一些应用程序使用Assemby.LoadWithPartialName来加载一个程序集的最高版本。如果最高版本是使用v4编译的,那么v2(3.0或3.5)的应用程序将无法加载它,并且应用程序将崩溃,即使有一个版本可以正常工作。最初,我们将GAC分区到其原始位置下,但这会导致某些Windows升级方案出现问题。这两个问题都涉及已经发布的代码,因此我们将我们的(版本分区的GAC移动到另一个地方。
这对大多数应用程序不会产生任何影响,并且不会增加任何维护负担。这两个位置只能使用本机GAC API访问或修改,这些API按预期处理分区。这种情况出现的地方是通过公开GAC路径的API,例如GetCachePath,或检查加载到托管代码中的mscorlib的路径。
值得注意的是,当我们发布v2并引入体系结构作为程序集标识的一部分时,我们还修改了GAC位置。这些添加了GAC_MSIL、GAC_32和GAC_64,尽管仍然在%windir%\assembly下。不幸的是,这对于此版本来说不是一个选项。
这样做似乎没有太多意义,原来的全局程序集缓存(GAC)已经能够存储不同版本的程序集。而且,几乎没有理由认为一个程序会意外引用错误的程序集,所有.NET 4程序集的[AssemblyVersion]都被提升到了4.0.0.0。新的进程内并行特性不应该改变这一点。
我的猜测是:已经有太多的.NET项目违反了“永远不要直接引用GAC中的任何内容”的规则。我在这个网站上看到过几次这样的情况。
唯一避免破坏这些项目的方法就是移动GAC。在微软看来,向后兼容性是神圣的。
Assembly.LoadWithPartialName
,如果GAC上有两个版本的程序集会发生什么? - Max Toro