代码改变世界

3.3 全局程序集缓存

2011-12-02 16:44  iRead  阅读(2076)  评论(0编辑  收藏  举报

  了解了如何创建强命名程序集之后,接着让我们讨论如何部署它,以及CLR如何利用特定的信息来定位并加载程序集。

  如果一个程序集要由多个应用程序访问,必须把它放到一个已知的目录中,而且CLR在检测到对该程序集的一个引用时,必须知道自动检查该目录。这个已知的位置称为全局程序集缓存(Global Assembly Cache,GAC。对于.NET3.5和以前的版本,GAC通常位于以下目录(假定Windows安装到C:\Windows目录):

         C:\Windows\Assembly

         对于.NET4.0,GAC位于以下目录:

         C:\Windows\Microsoft.NET\Assembly

  GAC目录是结构化的:其中包含许多子目录,并用一个算法来生成这些子目录的名称。永远不要将程序集文件手动复制到GAC目录;相反,应该使用工具来完成这项任务。这些工具知道GAC的内部结构,并指导如何生成正确的子目录名。

         开发和测试期间,为了在GAC中安装一个强命名程序集,最常用的工具是GACUtil.exe。直接运行这个工具,不添加任何命名行参数,会自动显示它的用法:

         Microsoft®.NET Global Assembly Cache Utility. Version 4.0.30319.1

         Copyright© Microsoft Corporation. All rights reserved.

         用法:Gacutil <命令> [<选项>]

         命令:

                   /i <assembly_path> [/r<…>] [/f]

                   将某个程序集安装到全局程序集缓存中

                   /il <assembly_path_list_file> [/r<…>][/f]

                   将一个或多个程序集安装到全局程序集缓存中

                   /u <assembly_display_name> [/r<…>]

                   将某个程序集从全局程序集缓存卸载

                   /ul <assembly_display_name_list> [/r<…>]

                   将一个或多个程序集从全局程序集缓存卸载

                   /l [<assembly_name>]

                   列出通过<assembly_name>筛选出的全局程序集缓存

                   /lr [<assembly_name>]

                   列出全局程序集缓存以及所有跟踪引用

                   /cdl

                   删除下载缓存的内容

                   /ldl

                   列出下载缓存的内容

                   /?

                   显示详细帮助屏幕

         选项:

                   /r <reference_scheme><reference_id><description>

                   指定要安装(/i,/il)或卸载(/u,/ul)的跟踪引用

                   /f

                   强制重新安装程序集

                   /nologo

                   取消显示徽标版权标志

                   /silent

                   取消显示所有输出

  可以看出,可以使用GACUtil.exe的/i开关将一个程序集安装到GAC中,使用/u开关则可从GAC中卸载一个程序集。注意,不能将一个弱命名的程序集放到GAC中。如果将一个弱命名的程序集的文件名传给GACUtil.exe,它会显示错误消息:“将程序集添加到缓存失败:试图安装没有强名称的程序集”。

注意:默认情况下,GAC只能由Windows Administrators组的成员操作。如果执行GACUtil.exe的用户不是这两个组的成员,GACUtil.exe将无法安装或卸载程序集。

  GACUtil.exe的/i开关方便开发人员在测试时使用。然而,用GACUtil.exe在生产环境中部署程序集时,建议在安装或卸载程序集时,除了指定GACUtil.exe的/i或/u开关,还要使用/r开关。/r开关将程序集与Windows的安装与卸载引擎集成在一起。简单地说,它告诉系统哪个应用程序需要程序集,并将应用程序与程序集绑定到一起。

注意:如果将强命名程序集打包到一个.cab文件中,或者以其他方式进行压缩,程序集的文件首先必须解压成临时文件,然后才能使用GACUtil.exe将程序集文件安装到GAC中。安装好程序集的文件之后,临时文件可以删除。

  GACUtil.exe工具没有与.NET Framework重分发包配套提供。如果应用程序含有一些需要部署到GAC的程序集,应该使用Windows Installer(MSI),因为MSI是用户机器上肯定会安装,又能将程序集安装到GAC中的工具。

重要提示:将程序集文件全局部署到GAC中,是对程序集进行注册的一种手段。虽然实际的Windows注册表没有受到任何影响,但将程序集安装到GAC中,会破坏我们的一个基本目标,即:简单地安装、备份、还原、移动和卸载应用程序。所以,建议程序员尽量避免全局部署,尽量使用私有部署。

  在GAC中“注册”程序集的目的是什么呢?假定两家公司分别生成了一个名为OurLibrary的程序集,两个程序集都有一个OurLibrary.dll文件构成。显然,这两个文件不能存储到同一个目录中,否则最后一个安装的会覆盖第一个安装的,肯定会破坏一个应用程序。相反,将程序集安装到GAC中,就会在C:\Windows\Assembly目录下创建专门的子目录,程序集文件会复制到其中一个子目录中。

  通常,没人会去检查GAC的子目录,所以GAC的结构对你来说并不重要。只要你使用的工具和CLR知道这个结构,一切都会正常进行。