zoukankan      html  css  js  c++  java
  • 在.net中使用GAC

    在.net中使用GAC

    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,结果如下:

    1 F:\WorkSpace\.net\DUtil\bin\Debug>sn -k DUtil.snk
    2   
    3 Microsoft (R) .NET Framework 强名称实用工具 版本 3.5.21022.8
    4 Copyright (c) Microsoft Corporation.  All rights reserved.
    5   
    6 密钥对被写入 DUtil.snk

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

    为程序集设置签名

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

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

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

    警告 1 使用命令行选项“/keyfile”或适当的项目设置代替“AssemblyKeyFile” F:\WorkSpace\.net\DUtil\Properties\AssemblyInfo.cs 38 12 DUtil

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

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

    安装到GAC

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

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

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

    1 F:\WorkSpace\.net\DUtil\bin\Debug>gacutil -i DUtil.dll
    2 Microsoft (R) .NET Global Assembly Cache Utility.  Version 3.5.21022.8
    3 Copyright (c) Microsoft Corporation.  All rights reserved.
    4   
    5 将程序集添加到缓存失败: 拒绝访问。您可能没有执行此任务的管理凭据。请与您的系统管
    6 理员联系以获得帮助。

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

    1 F:\WorkSpace\.net\DUtil\bin\Debug>gacutil -i DUtil.dll
    2 Microsoft (R) .NET Global Assembly Cache Utility.  Version 3.5.21022.8
    3 Copyright (c) Microsoft Corporation.  All rights reserved.
    4   
    5 程序集已成功添加到缓存中

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

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

    使用GAC的dll

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

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

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

    卸载GAC中的DLL

    一句话搞定

    01 C:\Windows\system32>gacutil -u DUtil
    02 Microsoft (R) .NET Global Assembly Cache Utility.  Version 3.5.21022.8
    03 Copyright (c) Microsoft Corporation.  All rights reserved.
    04   
    05 程序集: DUtil, Version=0.1.0.0, Culture=neutral, PublicKeyToken=35f4c1ba225b3cc6
    06 , processorArchitecture=MSIL
    07 已卸载: DUtil, Version=0.1.0.0, Culture=neutral, PublicKeyToken=35f4c1ba225b3cc6
    08 , processorArchitecture=MSIL
    09 卸载的程序集数 = 1
    10 失败次数 = 0

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

  • 相关阅读:
    第二十一章流 1流的操作 简单
    第二十章友元类与嵌套类 1友元类 简单
    第十九章 19 利用私有继承来实现代码重用 简单
    第二十章友元类与嵌套类 2嵌套类 简单
    第十九章 8链表类Node 简单
    第二十一章流 3用cin输入 简单
    第十九章 10 图书 药品管理系统 简单
    第十九章 11图书 药品管理系统 简单
    第二十一章流 4文件的输入和输出 简单
    第十九章 12 什么时候使用私有继承,什么时候使用包含 简单
  • 原文地址:https://www.cnblogs.com/ahghy/p/2153385.html
Copyright © 2011-2022 走看看