• 什么是publickeytoken及publickeytoken的作用


     

    概念:
    (一)DotNet中的版本组成
    DotNet中的版本由4个物理号码组成,如图(一) 

    图(一)
    在程序集里面,我们可以通过加上AssemblyVersion特性来设置它,
    如[assembly: AssemblyVersion("2.0.2.11")]
    (二) GAC:
    计算机范围内的代码缓存,它存储专门安装的程序集,这些程序集由计算机上的许多应用程序共享。在全局程序集缓存中部署的应用程序必须具有强名称,一个程序集如果注册到了GAC里,被其他程序集合引用的时候,将不会拷贝副本到引用的程序目录中。 (本文只讨论注册到GAC中的程序集)

    --------------------------------------------------------------------------------

    正文:
    (1) 我们现在开始写第一个组件
    它的版本号为 1.0.0.0 有一个类,包含一个简单的方法,该方法返回一个字符串
    代码如下,我都做了注解
    //首先生成强名称到文件中
    sn –k c:\Version.snk
    //写类文件

    v1.cs
    using System;
    using System.Reflection;
    [assembly: AssemblyKeyFile(
    @"c:Version.snk")]  //因为注册到GAC,所以使用强名称签名
    [assembly: AssemblyVersion("1.0.0.0")]   //设置版本号
    namespace V1
    {
        
    public class V1
        {
            
    public V1()
            {
            }
            
    public string GetVersion()
            {
            
    return "你好,我是版本1";
            }
        }
    }

    编译成组件 V1.dll
    拷贝这个V1.dll到 文件夹c:\V1
    把V1.dll注册到GAC
    Gacutil –I c:\V1\V1.dll
    系统显示注册成功
    (2) 然后我们编写一个控制台程序测试这个组件
    TestVersion.cs

    ///
    ///请添加对V1.dll(c:V1V1.dll)的引用,因为是在Gac里面,所以V1.dll不会在本地目录存在
    ///
    using System;
    namespace TestVersion
    {

        
    class TestVersion
        {
            
    static void Main(string[] args)
            {
                V1.V1 v1
    =new V1.V1();
                Console.WriteLine(v1.GetVersion());
                Console.Read();
            }
        }
    }

    编译后运行(TestVersion.exe)
    屏幕输出的结果是 :
    "你好,我是版本1"
    (3) 好了,一切很美好,过了几年了,我们得升级程序了
    现在来编写V1.dll升级版本,版本号为2.0.0.0
     v1.cs

    using System;
    using System.Reflection;
    [assembly: AssemblyKeyFile(
    @"c:Version.snk")] ///使用上面的强名称
    [assembly: AssemblyVersion("2.0.0.0")] ///注意,这里已经改了主版本号
    namespace V1
    {
        
    public class V1
        {
            
    public V1()
            {

            }
            
    public string GetVersion()
            {
            
    return "你好,我是版本2";///修改了输出的结果,这样我们才知道到底是运行了那个
            }
        }
    }

    编译 成组件 V1.dll
    拷贝这个V1.dll到 文件夹c:\V2
    把V1.dll注册到GAC
    Gacutil –I c:\V2\V1.dll
    (4) .现在来看看再次运行TestVersion.exe输出了什么东西
    是的,和原来的没有变化还是
    "你好,我是版本1"
    为什么不是"你好,我是版本2"?
    我们用ildasm.exe打开程序集TestVersion.exe 看看

    是的,它目前就是使用了版本1.0.0.0
    (5) 我们开始进行版本升级
    把TestVersion.exe使用的版本由1.0.0.0替换成版本2.0.0.0
    其实很简单的,给我们的 TestVersion.exe
    加个配置文件 TestVersion.exe.config里面打入

    <?xml version="1.0"?>
    <configuration>
      
    <runtime>
        
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
          
    <dependentAssembly>
            
    <assemblyIdentity name="V1" publicKeyToken=" 758fe4e9db9d8251"/>
            
    <bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0" />
          
    </dependentAssembly>
        
    </assemblyBinding>
      
    </runtime>
    </configuration>

    简单说明:
    assemblyIdentity 主要进行程序集合的标识
    其中 name是程序集的名称 publicKeyToken是公匙的标记;如何获得这些信息呢?很简单,打开%SystemDir%\assembly (我的是C:\WINNT\assembly)
    可以看到这些信息(如下图,你的机器上可能和我不一样)

    可以看到有两个V1(正确,我们确实注册了两个进去,版本也对) 我们开始用的是1.0.0.0的,记下公匙Token 写到publicKeyToken
    bindingRedirect 节点主要配置版本如何跳转
    oldVersion="1.0.0.0" newVersion="2.0.0.0" 很清楚的,就是如果TestVersion.exe使用的V1.dll是旧版本的,程序集版本号为1.0.0.0,那么就使用新的,版本号为2.0.0.0的程序集
    需要注意的是,oldVersion 可以使用范围来界定,如 oldVersion="1.0-1.9" 但是如果没有使用范围表示法的话,一定要写全版本号
    newVersion 不可以使用范围表示法,请写全版本号
    好了,现在再次运行TestVersion.exe
    输出的是: "你好,我是版本2",掌声!!!
    就是怎么简单!
    (6) 如果现在我们用ildasm.exe打开程序集TestVersion.exe,看到的内容将没有变化
    确实,是配置文件起了作用,整个过程没有对调用程序TestVersion.exe的代码做半点改动!
    (7) 配置错了会怎么样?:
    有可能的错误,比如newVersion写错了,根本没这个升级版本,将会抛出异常System.IO.FileNotFoundException,请注意处理

  • 相关阅读:
    Android webview 应用
    Android 访问权限设置
    Android应用----如何让应用全屏
    PHP基础
    递归在PHP中的应用举例
    软工实践个人总结
    2020软件工程实践第2次结对编程作业
    2020软件工程第一次结对作业
    2020软件工程实践第一次个人编程作业
    A brief introduction of myself
  • 原文地址:https://www.cnblogs.com/ghfsusan/p/1505201.html
Copyright © 2020-2023  润新知