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

Max*_*oro 300 .net gac .net-4.0

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

问题是,为什么?

Bri*_*ndy 180

是的,因为有2个不同的全局程序集缓存(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.他们不想破坏旧的应用程序.

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

例如,如果.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 2.0)应用程序的问题在Net Framework 4.0中重新出现,此时CLR 4.0已发布.因此,为了避免CLR 2.0和CLR 4.0之间的干扰问题,GAC现在分为每个运行时的私有GAC.

随着CLR在未来版本中的更新,您可以期待同样的事情.如果只有语言更改,那么您可以使用相同的GAC.

  • 该博客文章仅仅重述了OP的发现,它没有解释为什么*GAC需要拆分.不明显的是,最初的GAC能够完全保持4.0组件的分离.他们有一个新的[AssemblyVersion] (18认同)
  • 您应该从以下链接中引用这一点:"例如,如果.NET 1.1和.NET 2.0共享相同的GAC,那么从此共享GAC加载程序集的.NET 1.1应用程序可以获得.NET 2.0程序集从而破坏了.NET 1.1应用程序." (2认同)

Jas*_*asl 67

我还想知道为什么2 GAC并且发现Mark Miller.NET 4.0评论部分以下解释有2个全局程序集缓存(GAC):

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

谢谢你的帖子."干扰问题"故意含糊不清.在撰写本文时,问题仍在调查中,但很明显有几个破碎的情景.

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

这不会对大多数应用程序产生任何影响,也不会增加任何维护负担.只应使用本机GAC API访问或修改这两个位置,本地GAC API按预期处理分区.它所代表的地方是通过API公开GAC的路径(如GetCachePath),或检查加载到托管代码中的mscorlib的路径.

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

希望它能帮助未来的读者.

  • 米勒对链接文章的评论确实提供了内部人士对该主题的看法. (3认同)

Han*_*ant 66

它没有多大意义,原始的GAC已经能够存储不同版本的程序集.并且没有理由认为程序会偶然引用错误的程序集,所有.NET 4程序集都会使[AssemblyVersion]达到4.0.0.0.新的进程内并排功能不应改变这一点.

我的猜测:已经有太多的.NET项目打破了"永远不会引用GAC中的任何内容"规则.我已经在这个网站上看了好几次.

只有一种方法可以避免破坏这些项目:移动GAC.Back-compat在微软是神圣的.

  • 这是唯一试图解释*为什么*就是这种情况的答案.+1 (3认同)
  • @Max:您的计算机上有两个.NET程序集副本.这些是c:\ windows\microsoft.net和c:\ program files\reference程序集中的引用程序集.在运行时使用的是GAC @ c:\ windows\assembly.它们不一样,64位就是一个例子.Microsoft竭尽全力避免任何人使用shell扩展处理程序引用GAC.和"添加引用"对话框.不是100%有效 (2认同)
  • @Hans Passant:"并且没有理由认为程序会偶然引用错误的程序集"我认为这里的关键是`Assembly.LoadWithPartialName`,如果我们在GAC上有两个版本的程序集,会发生什么? (2认同)