什麼是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,請注意處理