GAC

一、GAC的作用

全称是Global Assembly Cache作用是可以存放一些有很多程序都要用到的公共Assembly,例如System.Data、System.Windows.Forms等等。这样,很多程序就可以从GAC里面取得Assembly,而不需要再把所有要用到的Assembly都拷贝到应用程序的执行目录下面。举例而言,如果没有GAC,那么势必每个WinForm程序的目录下就都要从C:\WINDOWS\Microsoft.NET\Framework\vX下面拷贝一份System.Windows.Forms.dll,这样显然不如都从GAC里面取用方便,也有利于Assembly的升级和版本控制。

二、强命名程序集

因为不同的公司可能会开发出有相同名字的程序集来,如果这些程序集都被复制到同一 个相同的目录下,最后一个安装的程序集将会代替前面的程序集。这就是著名的Windows “DLL Hell”出现的原因。

  很明显,简单的用文件名来区分程序集是不够的,CLR需要支持某种机制来唯一的标识一个程序集。这就是所谓的强命名程序集。

  一个强命名程序集包含四个唯一标志程序集的特性:文件名(没有扩展名),版本号,语言文化信息(如果有的话),公有秘钥。

  这些信息存储在程序集的清单(manifest)中。清单包含了程序集的元数据,并嵌入在程序集的某个文件中。

  下面的字符串标识了四个不同的程序集文件:

  “MyType, Version=1.0.1.0,

  Culture=neutral, PublicKeyToken=bf5779af662fc055”

  “MyType, Version=1.0.1.0,

  Culture=en-us, PublicKeyToken=bf5779af662fc055”

  “MyType, Version=1.0.2.0,

  Culture=neturl, PublicKeyToken=bf5779af662fc055”

  “MyType, Version=1.0.2.0,

  Culture=neutral, PublicKeyToken=dbe4120289f9fd8a”

  如果一个公司想唯一的标识它的程序集,那么它必须首先获取一个公钥/私钥对,然后将共有秘钥和程序集相关联。不存在两个两个公司有同样的公钥/私钥对的情况,正是这种区分使得我们可以创建有着相同名称,版本和语言文化信息的程序集,而不引起任何冲突。

  与强命名程序集对应的就是所谓的弱命名程序集。(其实就是普通的没有被强命名的程序集)。两种程序集在结构上是相同的。都使用相同的PE文件格式,PE表头,CLR表头,元数据,以及清单(manifest)。二者之间真正的区别在于:强命名程序集有一个发布者的公钥/私钥对签名,其中的公钥/私钥对唯一的标识了程序集的发布者。利用公钥/私钥对,我们可以对程序集进行唯一性识别、实施安全策略和版本控制策略,这种唯一标识程序集的能力使得应用程序在试图绑定一个强命名程序集时,CLR能够实施某些“已确知安全”的策略(比如只信任某个公司的程序集)。

三、如何创建强命名程序集, 如何查看强命名程序集的PublicKeyToken

如何创建强命名程序集

===================

1. 在Visual Studio中的class library工程上点右键, 选择properties.

2.  选择左边的Signing选项卡.

3. 勾选Sign the assembly复选框. 在下拉列表中选择<New...>.

4. 在弹出的对话框中给snk文件起一个名字. 按OK.

5. 程序集强命名完成.

如何查看强命名程序集的public key token

=========================

有时候你需要在web.config文件中或者其他地方引用自己写的强命名程序集, 你需要写入像下面这样的fully qualified name:

MyNamespace.MyAssembly, version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

前面三个部分比较容易获得, 因为是你自己写的, 你当然知道assembly的名字, 版本, 还有culture信息. 比较麻烦的部分是如何获得自己签名的程序集的public key token. 一种平常的方法是使用Reflector来打开自己的程序集, 然后获得token(实际上, Reflector会给你如同上面例子那样的完整信息). 但是这有的时候还是显得有点未免杀鸡用牛刀了. 如果你已经打开了Visual Studio, 那么仅仅是在VS的菜单里点一个菜单项就能获得答案不是更好么? 下面就是步骤.

1. 在Visual Studio中, 打开Tools菜单, 然后点击External Tools这个菜单项.

2. 在弹出的External Tools对话框中, 点击Add按钮.

3. 按照下图进行配置. sn.exe这个工具在不同版本的VS下处于不同的文件夹中. 最简单的找到它的方式是在VS Command Prompt中输入"where sn.exe". 在参数框里写入"-T $(TargetPath)". 然后勾选"Use Output Window". 这样的话, 结果就会在VS的output window. 然后点击OK,

4. 结果如图.

5. 在输出窗口可以看到结果. 这在你的solution里有多个project的时候也是可以正常工作的. 只需要点击一下Solution Explorer中的Project, 然后点击我们的菜单项就可以了.

四、如何将自己的dll注册到GAC中

在开发和测试中,最常用的工具就是GACUtil.exe。 在GAC注册程序集跟COM注册差不多,但相对更容易:
    1.把程序集添加到GAC中: GACUtil /i sample.dll (参数/i是安装的意思)
    2.把程序集移出GAC GACUtil /u sample.dll (参数/u就移除的意思)
注意:不能将一个弱命名程序集安装到GAC中。
如果你试图把弱命名程序集加入到GAC中,会收错误信息:”
    Failure adding assembly to the cache: Attempt to install an assembly without a strong name”
    d)强命名程序集的私有部署

例子:

C:\Program Files\Microsoft Visual Studio 8\VC>gacutil -i F:\myweb\BalloonShop\Cl
assLibrary1\bin\Debug\ClassLibrary1.dll

在C:\WINDOWS\assembly将会看到ClassLibrary1,注册成功

五、查看GAC文件内容以及将DLL复制出来

在项目中我们常常会引入第三方的dll,一般情况下我们都可以将所需的dll文件复制到硬盘上的一个地方,然后在项目中添加引用,这个操作很简单!但有时候我们会遇到这样的情况,就是所要引用的dll在目标机器的GAC里,这时我们就不能手动将它拷贝出来了。

其实Windows的GAC是有对应的目录的,一般来说为c:\Windows\assembly\,这个目录有一些特殊,它里面存放的是本机已安装和注册的类库dll,并且不允许用户直接对其中的元素进行相关操作(如复制、剪切、粘贴、修改名称等),不过你可以直接将另一位置的dll文件直接拖放到这个目录下进行dll的安装,但是我们不能直接将已经安装进去的dll再拷贝出来。这里我将介绍一种方法来完成这个操作。

首先我们切换到Windows的命令行方式,即开始-运行-cmd-回车,然后转到GAC所在的目录,利用dir命令查看一下其中的内容,如下图。

 似乎可以明白GAC中的目录结构了,基本上我们可以根据GAC目录中的Processor Architecture列来区分dir的类型,例如我们要找的System.Web.Extensions属于MSIL,在CMD方式下它应该就对应GAC_MSIL,然后切换到这个目录下并dir。

看到我们要找的System.Web.Extensions程序集了,它也是一个dir,继续切进去并dir。

这时只有一个目录了,继续切进去,然后dir就可以看到我们最终想要的dll文件了,然后通过copy命令将它复制出来就OK了!

小技巧:在CMD方式下使用命令时,如果要输入的文件名或目录名太长,可以先敲部分字符,然后通过Tab键自动补全,Windows的command工具会自动为你找到相匹配的内容!

六、例子

如上图所示,新建了2个类库文件:ClassLibrary1、ClassLibrary2

1、使用上面的第三点创建了强类型程序集ClassLibrary1,并且注册到GAC中(可以使用上面第三点的方法,也可以使用反编译器进行反编译,可以查看到PublicKeyToken值。ClassLibrary2为null,ClassLibrary1为568e03e6162a7a2e)。

2、在DataAccess中引用ClassLibrary1、ClassLibrary2,编译DataAccess。

3、进入DataAccess工程的bin\debug文件夹下,只有ClassLibrary2.dll与DataAccess.dll(没有ClassLibrary1.dll)

由此可知:程序是从GAC中直接取得ClassLibrary1.dll的而不是从ClassLibrary1工程中将ClassLibrary1.dll拷贝到自身的debug中进行引用。

GAC: Global Assembly Cache相关推荐

  1. 将.NET dll注册到GAC(Global Assembly Cache)中

    当发现有多个解决方案引用一个dll时,为了不重复引用所以将.net的一个dll注册到GAC中去. gacutil.exe. 开始菜单-Microsoft Visual Studio 2008 -Vis ...

  2. [转]程序集之GAC---Global Assembly Cache

    本文转自:http://www.cnblogs.com/jhxk/articles/2564295.html 1.什么是GAC?GAC解决什么问题? GAC全称为: Global Assembly C ...

  3. The global shader cache file'X:/XXXX/GlobalShaderCache-PCD3D_SM5.bin' is missing——UE4工程运行失败

    今天在学习UE4的时候,新建一个C++工程,编译启动后在编辑器里添加了一个新的类.然后我停止了编辑器的运行,进行简单的修改后发现可以生成却不能运行,提示如下. 提示我一个全局的shader缓存文件丢失 ...

  4. .NET框架程序设计--Globally Deployment Assembly全局部署程序集

    Globally Deployment Assembly全局部署程序集 (一)StrongName Assembly Strongly Named Assembly是CLR唯一标识程序集的机制,包含4 ...

  5. 了解GAC:从“找不到Microsoft.SqlServer.SqlClrProvider.dll”的问题开始

    了解GAC:从"找不到Microsoft.SqlServer.SqlClrProvider.dll"的问题开始                             老帅     ...

  6. 关于GAC全局程序集缓存

    GAC 与其物理路径 GAC (Global Assembly Cache) 是 .NET 框架下程序集(Assembly)的一个全局缓存.不同 CLR (Common Language Runtim ...

  7. 2017 .NET 開發者須知

    筆記-Scott Hanselman 的 2017 .NET 開發者須知 转载http://blog.darkthread.net/post-2017-01-16-dotnet-dev-should- ...

  8. c# 5.0入门经典笔记

    第一章: c# 关键字 char 别名Char 单个16位Unicode字符.decimal 128位用于金融计算. 可以为null的类型(包括值和引用类型)都支持null合并运算符(??) int? ...

  9. WebPart的三种部署方法

    部署Web部件的三种方法:<?XML:NAMESPACE PREFIX = O /> 1.手工部署 2.CAB文件部署 3.MSI文件部署 首先来介绍手工部署方法,可以根据我的另一篇文章& ...

最新文章

  1. 深圳出台数据中心PUE新政,或将开启千亿级节能市场
  2. apache camel_令人印象深刻的第一个Apache Camel版本
  3. Pandas系列(十二)实现groupby分组统计
  4. Laravel学习笔记之Demo1——URL生成和存储
  5. CPU虚拟化技术解析
  6. shell 截取ip地址最后一位_shell脚本获取IP地址段的方法
  7. 计算机主机启动不了系统怎么办,电脑蓝屏开不了机怎么办
  8. 2022-2028全球造水机市场现状及未来发展趋势
  9. Adobe帝国的产品线
  10. 交换机运维-排查用户反应网速卡的问题
  11. asp数组函数LBound 、UBound和Split
  12. 淘宝产品,为什么转化率还是这么低?
  13. R语言和RStudio开发环境的下载与安装
  14. Jenkins日程配置说明
  15. 约瑟夫环——递推公式详解(leetcode 1823. 找出游戏的获胜者)
  16. 教你如何用手机下载视频号[微信小程序]中的视频
  17. 异构计算给我们带来了哪些思考?
  18. iOS开发--- iOS编程浅析
  19. el-descriptions 跨列和相关样式
  20. Redux 使用教程

热门文章

  1. 苹果HomePod 2月9日上市 何时登陆中国仍未知
  2. js上传视频并获取视频帧做为封面
  3. 大数据测试前需要了解性能测试点
  4. linux怎么进入root文件,在Linux上打开具有Root访问权限的程序
  5. 深度学习Week3-天气识别(Pytorch)
  6. 有道高调进入在线教育,要怎么做?
  7. 保姆级教学 nps内网穿透实现Windows远程桌面 宝塔
  8. 企业QQ和个人QQ同时登陆方法
  9. 饿了么、口碑实现超30亿美元独立融资,阿里、软银为投资方
  10. 服务端朋友圈接口代码的编写和理解