zoukankan      html  css  js  c++  java
  • Chapter3 共享程序集和强命名程序集

    1.1两种程序集,两种部署

    哪两种程序集?
    CLR支持两种程序集:弱命名程序集(weakly named assembly)和强命名程序集(strongly named assembly)
    两种程序集的共同点?
    结构上完全一致:相同的PE文件格式、PE32(+)头、CLR头、元数据、清单表以及IL。
    生成工具相同:C#编译器或者AL.exe
    两种程序集的区别?
    强命名程序集使用了发布者的公钥/私钥对进行了签名,它唯一标识了程序集的发布者,这对密钥允许对程序集进行唯一性的标识、保护和版本控制,允许程序集部署到用户机器的任何地方,甚至可以部署到Interne。
    上面介绍了两种程序集,下面在介绍两种部署
    一个程序集可以采取两种方式来部署:
    1.私有,私有部署的程序集:指部署到应用程序基目录或者一个子目录中的程序集,(弱命名程序集只能以私有的方式部署)。
    2.全局,全局部署的程序集:指部署到一些已知位置的程序集。(强命名程序集既可以私有部署,也可以全局部署)

    1.2为程序集分配强名称

    一个强命名程序集具有4个重要的Attributes,它们对程序集进行了唯一性标识:
    ①一个文件名(不计扩展名)
    ②一个版本号
    ③一个语言文化标识
    ④一个公钥(公钥标记public key token,小的哈希值)
    例如:

    "MyTypes, Version=1.0.8123.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
    "MyTypes, Version=1.0.8123.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"

    以上标识了2个完全不同的程序集文件
    这样一来,两家公司就可以创建具有相同名称、版本和语言文化的程序集,同时不会造成任何冲突
    生成一个公钥/私钥对:
    1.使用SN.exe来获取一个密钥

    SN -k MyCompany.snk

    这个命令行告诉SN.exe创建一个名为MyCompany.snk的文件,文件中包含二进制形式的公钥和私钥
    2.创建一个只包含公钥的文件(从MyCompany.snk文件中提取公钥并将其存储在MyCompany.PublicKey中)

    SN -p MyCompany.snk MyCompany.PublicKey

    3.显示公钥和MyCompany.snk包含的公钥的标记

    SN -tp MyCompany.PublicKey

    1.3全局程序集缓存

    如果一个程序集要由多个应用程序访问,必须把它放到一个已知的目录中,而且CLR在检测到对该程序集的一个引用时,必须知道自动检查该目录,这个已知的目录成为全局程序集缓存(GAC)
    .net 3.5和以前版本GAC通常位于C:\Windows\Assembly
    .net 4.0位于C:\Windows\Microsoft.NET\Assembly
    不要尝试手动复制程序集文件到GAC目录中,相反需要用GACUtil.exe工具在GAC中安装一个强命名程序集(注意弱命名程序集不能放到GAC中)

    1.4在生成的程序集中引用一个强命名程序集

    利用csc.exe 的/reference开关来指定想要引用的程序集文件名
    如果文件名是个完整的路径,csc.exe会加载指定的文件,并根据它的元数据来生成程序集
    如果只是单纯的一个文件名,则csc.exe会尝试在以下目录查找需要引用的程序集(按所列出的顺序):
    1.工作目录
    2.包含CSC.exe本身的目录,目录中还包含CLR的各种DLL文件
    3.使用/lib编译器开关指定的任何目录
    4.使用LIB环境变量指定的任何目录

    1.5强命名程序集能防范篡改

    用一个私钥对程序集进行签名,可以保证程序集是由对应公钥的持有者生成的。程序集安装到GAC时,系统对包含清单的那个文件的内容进行哈希处理,并将哈希值与PE文件中签入的RSA数字签证进行比较,如果两个值完全一致,表明文件内容未被篡改。

    1.6延迟签名

    当准备对自己的强命名程序集进行打包时,必须使用受到严密保护的私钥(大企业们会把它放到硬件设备中比如智能卡)对它进行签名。
    然而在开发和测试程序集时,访问这些私钥可能有些费事,所以.net framework提供了对延迟签名的支持。
    延迟签名允许你只能用公司的公钥来生成一个程序集,暂时不用私钥。在打包和部署程序集时,肯定会签名的。
    使用延迟签名技术开发程序集的步骤:
    1.开发程序集期间,获取只包含你的公司的公钥的一个文件,使用/keyfile和/delaysign编译器开关编译程序集:
    csc /keyfile:MyCompany.PublicKey /delaysign MyAssembly.cs
    2.生成程序集之后,执行以下命令,使CLR暂时信任程序集的内容,不对它进行哈希处理,也不比较哈希值,使其顺利的安装到GAC(如果有必要的话),现在可以生成引用这个程序集的其他程序集了,并可以随意测试。注意:在每台开发用的机器上,以下命令行都只需执行一次
    SN.exe -Vr MyAssembly.dll
    3.准备好打开和部署程序集时,请获取你的公司的私钥,然后执行以下命令,如果愿意,可以将这个新版本安装到GAC中
    SN.exe -R MyAssembly.dll MyCompany.PrivateKey
    4.为了在实际环境中测试,请执行以下命令,重新启动对这个程序集的验证:
    SN.exe -Vu MyAssembly.dll

    1.7私有部署强命名程序集

    在GAC中安装程序集具有几方面优势?
    1.GAC使程序集能被多个应用程序共享,减少总体物理内存占用
    2.很容部署一个新版本的程序集到GAC中,让所有应用程序通过一个发布者策略来使用这个新版本
    3.GAC还实现了对程序集多个版本的并行管理

    1.8运行时如何解析类型引用

    解析一个引用类型时,CLR可能以下三个地方找到类型
    1.同一个文件,编译时发现对相同文件中的类型访问
    2.不同文件,同一程序集
    3.不同的文件,不同的程序集
    解析一个引用类型时,如果发生任何错误(比如找不到文件、文件无法加载、哈希值不匹配等),就会抛出一个相应的异常。
    如下图:基于引用了一个方法或类型的IL代码,CLR如何利用元数据来定位一个类型定义的程序集

    1.9高级管理控制(配置)

    CLR如何利用XML配置文件来定位移动的文件

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
    <runtime>
    <assemblyBinding >
    <probing privatePath="AuxFiles;bin\subdir" xmlns="urn:schemas-microsoft-com:asm.v1"/>
    <dependentAssembly>
    <assemblyIdentity name="JeffTypes" publicKeyToken="32ab4ba45e0a69a1" culture="neutural"/>
    <bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0"/>
    <codeBase version="2.0.0.0" href="http://www.Wintellect.com/JeffTypes.dll"/>
    </dependentAssembly>
    <dependentAssembly>
    <assemblyIdentity name="TypeLib" publicKeyToken="1f2e74e897abbcfe" culture="neutural"/>
    <bindingRedirect oldVersion="3.0.0.0-3.5.0.0" newVersion="4.0.0.0"/>
    <publisherPolicy apply="no"/>
    </dependentAssembly>
    </assemblyBinding>
    </runtime>
    </configuration>

    1.probing元素
    查找一个弱命名程序集时,检查应用程序基目录AuxFiles和bin\subdir子目录。对于一个强命名程序集,CLR会检查GAC或由codeBase元素指定的URL。如果没有指定codeBase元素,CLR才会在应用程序的私有路径中检查强命名的程序集
    2.第一个dependentAssembly、assemblyIdentity、bindingRedirect元素
    查找控制着公钥标识32ab4ba45e0a69a1的那个组织发布的、语言文化为中性的JeffTypes程序集的1.0.0.0版本时,改为同一个程序集的2.0.0.0版本
    3.codeBase元素:查找由控制着公钥标识32ab4ba45e0a69a1的组织发布的、语言文化为中性的JeffTypes程序集的2.0.0.0版本时,尝试在URL处发现它http://www.Wintellect.com/JeffTypes.dll
    4.第二个dependentAssembly、assemblyIdentity、bindingRedirect元素
    查找由控制这公钥标识为1f2e74e897abbcfe的那个组织发布的、语言文化为中性的TypeLib程序集的3.0.0.0到3.5.0.0版本时,改为定位同一个程序集的4.0.0.0版本
    5.publisherPolicy元素
    如果生成TypeLib程序集的组织部署了一个发布者策略文件,CLR应该忽略该文件

    发布者策略控制

    例如企业刚刚创建了一个程序集的新版本,并修复了几个bug,打包要发送给所有用户的新程序集时,应同时创建一个XML配置文件,和上面的差不多,
    现在作为发布者,可创建包含这个发布者策略配置文件的一个程序集,为了创建发布者策略程序集,要像下面这样运行AL.exe
    AL.exe /out:Policy.1.0.JeffTypes.dll
    /version:1.0.0.0
    /keyfile:MyCompany.snk
    /linkresource:JeffTypes.config
    /out 开关指示AL.exe创建一个新的PE文件,本例就是Policy.1.0.JeffTypes.dll
    /version 开关标识发布者策略程序集的版本,这个与JeffTypes程序集本身无关。
    /keyfile 开关指示AL.exe使用发布者的“公钥/私钥”对发布者策略程序集进行签名,这个密钥必须匹配于所有JeffTypes程序集版本
    /linkresource 开关告诉AL.exe将XML配置文件作为一个资源连接(而非嵌入)到程序集
    如果新的程序集引入的bug比修复的bug还要多,可以忽略发布者策略程序集
    <publisherPolicy apply="no"/>

  • 相关阅读:
    tar命令,vi编辑器
    Linux命令、权限
    Color Transfer between Images code实现
    利用Eclipse使用Java OpenCV(Using OpenCV Java with Eclipse)
    Matrix Factorization SVD 矩阵分解
    ZOJ Problem Set
    Machine Learning
    ZOJ Problem Set
    ZOJ Problem Set
    ZOJ Problem Set
  • 原文地址:https://www.cnblogs.com/hailiang2013/p/2853351.html
Copyright © 2011-2022 走看看