zoukankan      html  css  js  c++  java
  • GAC

    GAC是什么?是用来干嘛的?GAC的全称叫做全局程序集缓存,通俗的理解就是存放各种.net平台下面需要使用的dll的地方。GAC的具体目录在windows/ assembly。

    喜欢使用破解软件的朋友可能会经常使用替换DLL这招,这个DLL虽然和.net下面的DLL有所不同,但大致起的作用还是一样的:使用共同的动态链接库来提高库复用 ,减少文件体积。在.net平台之前,程序们都把可能用到的公共DLL存放到system32文件夹下。由于版本的不一致及其他原因(将控制信息存放到注册表),造成 了很有名的DLL Hell

    最近在读俞甲子的《程序员的自我修养》,中间花了很大的篇幅描述程序编译中 的链接这个过程。而比较巧合的是,我的《C#与.NET 3.5高级程序设计》也正好读到程序集这一块。微软使用了GAC来避免DLL重蹈覆辙。现在,我就来部署一个简单的通用类库到GAC中。

    获取强名称(签名)

    并不是随便一个DLL都可以放到GAC中,如果这样的话,和之前的DLL Hell也没什么区别了。GAC使用一个强名称(签名)的方式来区分不同的DLL。每个签名 都是独一无二的公钥私钥对。现在我们使用SDK的sn工具为我的DUtil库生成一个snk签名。

    打开SDK中的Visual Studio 2008 命令提示,键入sn -k DUtil.snk,结果如下:

    F:WorkSpace.netDUtilbinDebug>sn -k DUtil.snk

    Microsoft (R) .NET Framework 强名称实用工具 版本 3.5.21022.8

    Copyright (c) Microsoft Corporation. All rights reserved.

    密钥对被写入 DUtil.snk

    这样我们就得到了一个snk签名文件。

    为程序集设置签名

    现在我们得到了一个签名文件,但是还没有把这个签名应用到程序中,在程序的assembly.cs文件中加入[assembly: AssemblyKeyFile("dutil.snk")],这个dutil.snk可以是绝对路径,我使用的是主目录中的snk文件。

    编译解决方案,生成的.dll文件就包含了签名。

    此时编译器会出现一个警告:

    警告 1 使用命令行选项"/keyfile"或适当的项目设置代替"AssemblyKeyFile" F:WorkSpace.netDUtilPropertiesAssemblyInfo.cs 38 12 DUtil

    既然VS建议我们用选项设定,那我们就用项目选项页设定key。如下图所示:

    PS:我测试过,生成DLL之后,就算删除签名使用的snk文件,依然可以正常使用。即snk文件只有在编译时候使用。

    安装到GAC

    安装到GAC有两种办法,一种是把DLL拖入windows/assembly目录下(不是复制粘贴,是拖动),另外一种是使用gacutil。

    在Win7下,拖动的话会遇到权限问题,如下图所示

    在gacutil下面也会遇到如下错误

    F:WorkSpace.netDUtilbinDebug>gacutil -i DUtil.dll
    Microsoft (R) .NET Global Assembly Cache Utility.  Version 3.5.21022.8
    Copyright (c) Microsoft Corporation.  All rights reserved.

    将程序集添加到缓存失败: 拒绝访问。您可能没有执行此任务的管理凭据。请与您的系统管

    理员联系以获得帮助。

    解决的办法就是进入命令行时候用管理员身份进入,执行之后显示如下

    F:WorkSpace.netDUtilbinDebug>gacutil -i DUtil.dll
    Microsoft (R) .NET Global Assembly Cache Utility.  Version 3.5.21022.8
    Copyright (c) Microsoft Corporation.  All rights reserved.

    程序集已成功添加到缓存中

    这时候查看windows/assembly目录,就会发现DUtil已经在里面了。

    用TotalCommander打开windows/assembly,会发现里面有GAC/GAC_32/GAC_MSIL这几个文件夹,我的DUtil安装到c: WindowsassemblyGAC_MSILDUtil.1.0.0__35f4c1ba225b3cc6DUtil.dll,这个路径包含了版本,签名,通过 这种方式,就能避免版本和错误dll的问题了。

    使用GAC的dll

    打开任意一个项目,添加引用时候,选择编译出来的DUtil.dll即可。查看具体属性,就会发现,这个DLL并未复制到本地,因为它可以从GAC中获取了。

    image

    这时候如果我们删除引用地方的DLL,会发现程序依然可以正确跑起来,说明我们的DLL确实来自GAC。(Update:当引用DLL文件存在时候,优先引用此DLL ,不存在才引用GAC的DLL)

    PS:不要尝试去打开windows/assembly目录来引用,你会发现你徒劳的。

    卸载GAC中的DLL

    一句话搞定

    C:Windowssystem32>gacutil -u DUtil
    Microsoft (R) .NET Global Assembly Cache Utility.  Version 3.5.21022.8
    Copyright (c) Microsoft Corporation.  All rights reserved.

    程序集: DUtil, Version=0.1.0.0, Culture=neutral, PublicKeyToken=35f4c1ba225b3cc6

    , processorArchitecture=MSIL

    已卸载: DUtil, Version=0.1.0.0, Culture=neutral, PublicKeyToken=35f4c1ba225b3cc6

    , processorArchitecture=MSIL

    卸载的程序集数 = 1

    失败次数 = 0

    这样就把特定目标的DLL卸载了。

  • 相关阅读:
    Hibernate之Query接口的uniqueResult()方法
    一个安静的地方
    AJAX实现简单的省市二级联动
    为了你们,而活着。
    PL/SQL Developer 连接远程Oracle数据库
    dotfuscator混淆的问题
    查询表内属于主键的列SQLServer2005
    关于net2.0里面新出现的类backgroundworker的应用 引用自http://www.cnblogs.com/dlwang2002/archive/2006/12/07/585093.html
    SQLServer int to base16
    数据库查询问题日期格式
  • 原文地址:https://www.cnblogs.com/bruce1992/p/14112044.html
Copyright © 2011-2022 走看看