为什么要用强命名Assemly?
1.防止其他Assembly与己方Assembly命名相同,造成错误
2.拥有独立命名的Assembly更方便进行版本管理与控制。当出现错误时,可采取策略回到原来某版本。
组成格式
"MyTypes, Version=1.0.8123.0, Culture=neutral, PublicKeyToken=xxxxx"
创建强命名Assembly
1.创建密钥对
采用非对称加密技术(公用,私用密钥)检查Assembly的一致性。
使用自带工具SN.exe
方法一: VS Command Prompt 创建
sn -k MyKey.snk --创建文件MyKey.snk 包含密钥对,以二进制形式保存
sn -p MyKey.snk MyKey.PublicKey --创建文件只包含Public Key
sn -tp MyKey.PublicKey --直接转换文件只包含Public Key
执行上句得到如下结果:
Microsoft (R) .NET Framework Strong Name Utility Version 4.0.20928.1
Copyright (c) Microsoft Corporation. All rights reserved.
Public key is
00240000048000009400000006020000002400005253413100040000010001003f9d621b702111
850be453b92bd6a58c020eb7b804f75d67ab302047fc786ffa3797b669215afb4d814a6f294010
b233bac0b8c8098ba809855da256d964c0d07f16463d918d651a4846a62317328cac893626a550
69f21a125bc03193261176dd629eace6c90d36858de3fcb781bfc8b817936a567cad608ae672b6
1fb80eb0
Public key token is 3db32f38c8b42c9a
可见public key很复杂,为了方便采用64位hash该key,取后16位作为public key token。
2.已经创建好钥匙了,那么就是编译了:
csc /keyfile:MyKey.snk MyProgram.cs
这样编译器就用private key签名了Assembly,并将public key植入manifest。 --这里只签名了manifest
方法2: 直接用VS,打开项目属性,签名,签名Assembly, <新建..>,选择Strong Name Key输入就OK了。这里有延迟签名,作用下面介绍。
部署强命名Assembly
使用Gacutil(Global Assembly Cache)。--GAC是存储专门指定的程序集以供计算机上多个应用程序共享的程序。
具体用法
参数
参数 | 说明 |
---|---|
assemblyName |
程序集的名称。可以提供部分指定的程序集名称(如 myAssembly)或完全指定的程序集名称(如 myAssembly, Version=2.0.0.0, Culture=neutral, PublicKeyToken=0038abc9deabfle5)。 |
assemblyPath |
包含程序集清单的文件的名称。 |
assemblyListFile |
列出要安装或卸载的程序集的 ANSI 文本文件的路径。若要使用文本文件安装程序集,请在文件中的单独一行上分别指定每个程序集的路径。全局程序集缓存工具解释相对于 assemblyListFile 的位置的相对路径。若要使用文本文件卸载程序集,请在文件中的单独一行上分别为每个程序集指定完全限定的程序集名称。请参见本主题后面的 assemblyListFile 内容示例。 |
选项 | 说明 | ||
---|---|---|---|
/cdl |
删除下载缓存的内容。 |
||
/f |
与 /i 或 /il 选项一起指定此选项将强制重新安装程序集。如果全局程序集缓存中已经存在同名的程序集,全局程序集缓存工具将改写该程序集。 |
||
/h[elp] |
显示该工具的命令语法和选项。 |
||
/i |
将程序集安装到全局程序集缓存中。 |
||
/ifassemblyPath |
将程序集安装到全局程序集缓存中。如果全局程序集缓存中已经存在同名的程序集,全局程序集缓存工具将改写该程序集。 指定此选项相当于同时指定 /i 和 /f 选项。 |
||
/il |
将 assemblyListFile 中指定的一个或多个程序集安装到全局程序集缓存中。 |
||
/irassemblyPath scheme id description |
将程序集安装到全局程序集缓存中,并添加引用以对程序集进行计数。使用此选项时必须指定assemblyPath、scheme、id和 description 参数。有关可为这些参数指定的有效值的说明,请参见 /r 选项。 指定此选项相当于同时指定 /i 和 /r 选项。 |
||
/l[assemblyName] |
列出全局程序集缓存的内容。如果指定 assemblyName 参数,则全局程序集缓存工具只列出与该名称匹配的程序集。 |
||
/ldl |
列出下载文件缓存的内容。 |
||
/lr[assemblyName] |
列出所有程序集及其相应的引用数。如果指定 assemblyName 参数,则该工具只列出与该名称匹配的程序集及其相应的引用数。 |
||
/nologo |
取消显示 Microsoft 启动标题。 |
||
/r[assemblyName | assemblyPath] scheme id description |
指定对要安装或卸载的一个或多个程序集的跟踪引用。与 /i、/il、/u 或 /ul 选项一起指定此选项。 若要安装程序集,请在使用此选项的同时指定 assemblyPath、scheme、id和 description 参数。若要卸载程序集,请指定 assemblyName、scheme、id和 description 参数。 若要移除对程序集的引用,必须指定在安装程序集时使用 /i 和 /r(或 /ir)选项指定的 scheme、id 和description 参数。如果卸载程序集,则全局程序集缓存工具还从全局程序集缓存中移除该程序集,条件是它是最后一个要移除的引用,并且 Windows Installer 没有对该程序集的未决引用。 scheme 参数指定安装方案的类型。可以指定以下值之一:
为 id 参数指定的值取决于为 scheme 参数指定的值:
description 参数允许您指定关于要安装的应用程序的描述性文本。当枚举引用时,显示此信息。 |
||
/silent |
取消所有输出的显示。 |
||
/uassemblyName |
从全局程序集缓存中卸载程序集。 |
||
/ufassemblyName |
通过移除对程序集的所有引用来强制卸载指定的程序集。 指定此选项相当于同时指定 /u 和 /f 选项。
|
||
/ul |
从全局程序集缓存中卸载 assemblyListFile 中指定的一个或多个程序集。 |
||
/u[ngen]assemblyName |
从全局程序集缓存中卸载指定的程序集。如果指定的程序集存在现有引用数,则全局程序集缓存工具显示引用数,而且不从全局程序集缓存中移除该程序集。
在 .NET Framework 1.0 和 1.1 版中,指定 /ungen 将使 Gacutil.exe 从本机映像缓存中移除该程序集。此缓存存储了使用本机映像生成器 (Ngen.exe) 创建的程序集的本机映像。 |
||
/urassemblyName scheme id description |
从全局程序集缓存中卸载对指定程序集的引用。若要移除对程序集的引用,必须指定在安装程序集时使用 /i和 /r(或 /ir)选项指定的 scheme、id 和 description 参数。有关可为这些参数指定的有效值的说明,请参见 /r 选项。 指定此选项相当于同时指定 /u 和 /r 选项。 |
||
/? |
显示该工具的命令语法和选项。 |
一般用法
gacutil /i MyProgram.dll
延迟签名
由于private key需要进行保护。所以当测试发布Assembly的时候该问题变得很麻烦(因为从上面方法可知必须要Private Key)。于是就提供了一种方式,只需要Public Key。当使用了延迟方法时,Assembly将不再被Hash.
具体使用方法:
1.创建Assembly使用延迟签名
csc /keyfile:MyKey.PublicKey /delaysign MyProgram.cs
2.使CLR信任该Assembly,并不适用Hash以及压缩
SN.exe -Vr MyAssembly.dll
3.已经准备好部署Assembly,赋予源PrivateKey
SN.exe -R MyAssembly.dll MyKey.PrivateKey
4.测试,打开验证。
SN -Vu MyAssembly.dll
使用GAC部署好处:
1.部署到GAC中,使得很多程序都能共享使用该Assembly,减少物理空间的浪费。
2.更新时,可以很方便的时所有程序转换成使用该新部署的Assembly。
3.安全性更高。只有有管理权限的人(Private Key)才能修改Assembly。
--注意:GAC解决的是Assembly共享,当不需要共享时则不推荐这么做