程序集即代码组,可以是单个文件或多个文件,按一个整体部署,但可指定自身调用其他程序集的版本。
- 推出原因
为解决dll地狱而推出,也可解决其他问题。dll地狱,a应用使用dll版本1,b应用使用dll版本2,传统的com(一般用dll执行)模式,会自动调用最新版本的dll,如果这个dll不向后兼容(大多dll都不向后兼容),导致装了b应用后,a应用不能使用。
.net模式,在程序集中,指定使用哪个版本,在调用时,默认使用指定的版本,解决了dll地狱问题。
- 程序集信息
主版本,次版本、修订号、内部版本号
公司公钥
程序集人类友好名称
程序清单。包含在一个可执行文件中,或表示为一个独立的文件。
提供的自定义类型
引用其他程序集的信息。名称、版本、区域性和公钥。
- 类型元数据。程序集提供给外部使用的自定义类型
- msil代码。各种语言最终被编译成的代码,这代码能被clr执行
- 资源。通常指图片、本地化翻译文本等被塞入程序集的所有其他文件。
- 构建程序集
写入上述程序集信息,还可以自定义特性,设置一般特性是[assembly:AttributeName("AttibuteValue")]注意不是语言的一部分,但在程序文件中,不用分号。要引用system.Reflection空间。程序集信息也可以在VS的解决方案管理器,项目文件,右键属性设置。
- 创建单文件程序集
用csc 程序集文件名 或VS的生成,可生成可执行程序集。在VS,程序集信息保存在AssemblyInfo.cs的单独文件里,特别说明的是公钥,用微软网站上的sn.exe生成,在这个文件里指明路径和文件名mykey.snk,这个公钥文件名需要唯一,不与已有的其他公司或本公司其他公钥相同。
程序集可没有main方法,此时是作为库程序集使用,可用命令行编译为dll,csc out: 期望文件名 :library 源代码文件名
- 创建多文件程序集
必须用命令行工具创建多文件程序集,使用csc和程序集链接器al。不能为VS内的C#应用程序创建多文件程序集。
C#文件A包含方法,没入口,定义了命名空间namespaceA;文件B包含main,引用了namespaceA;文件C包含程序集清单信息;单独的位图文件D.bmp。
编译文件A成模块文件A.netmodule,没编译成库文件 csc /t:module A.cs;编译文件B,告诉编译器找A文件中的命名空间 csc /addmodule:A.netmodule /t:module B.cs;编译C成单独的模块 csc /t:module C.cs;最后用程序集链接器al将这4个文件一起并入可执行文件 al A.netmodule b.netmodule c.netmodule /embed:D.bmp /main:B.Main /out:A.exe
- 查看程序集内容
用反汇编命令ildasm outABCD.exe,ILDasm只能反汇编.net文件,也可通过启动微软SDK里的ILDasm查看。
- 强名称和签名
运行时,用来防止恶意代码代替可信任代码,强名称可保证特定程序集自编译以来,内容是否没有被更改;代码签名,为程序集提供一个信任级。
给程序集指定强名称,就是将公钥加密应用到程序集。公钥加密包括公钥和私钥各一个,公钥全世界公用,私钥是严格保守的秘密。一种加密方法是程序集由公钥加密,再由匹配的私钥解密,这种使用人都有秘密了;另一种方法是程序集由私钥签名,用公钥验证,这种使用人不必有秘密,.net采用这种。
使用强名称中密钥的过程。开发库时,确定程序集的密钥;创建程序集时,把私钥给程序集的哈希;使用程序集的程序,包括这个私钥对应的公钥;运行时,clr用第2个文件的公钥,检验第1个文件中的哈希,是否是预期的私钥签名;随后,哈希可检验第1个文件的内容是否被篡改过(没改过的,能与程序集的文件匹配)。
指定强名称的方法。可以使用sn.exe创建密钥对,-K开关 sn -k A.snk;在程序集的源代码中使用AssenmblyKeyFileAttribute特性;使用al把密钥和程序集链接起来,al A.netmodule b.netmodule c.netmodule /embed:D.bmp /main:B.Main /out:A.exe /t:exe /keyfile:A.snk;另一个程序集使用此程序集,可以在编译那个程序集时,使用/reference开关来检索公钥。
- 代码签名
强名称判断程序集是否被篡改,保证不了篡改前的最初文件没有恶意代码。这里是第二种安全机制,给程序集添加Authenticode数字签名。使用Authenticode签名的程序集,证明其发行者已经过公认授权机构的证书授权。取得证书授权,需要提供省份证明和一定费用。
准备过程是。.net框架有证书创建工具makecert -n "公司名" -sv 包含证书私钥的文件.pvk 证书名.cer,运行时,会需要指定私钥文件的密码;转换证书cert2spc X_509证书名.cer 软件发行者证书名.spc;文件签名工具signcode给程序集签名,启动向导,选程序集文件,自定义,从文件选择刚才的软件发行者证书.spc文件,指定A.snk私钥文件,私钥密码,散列算法,完成;
证书验证工具chktrust A.exe 运行后,如果不是公认的证书授权机构签发的,会有警告信息,是公认的,会显示是哪个机构授权的。
- 程序集版本控制
版本号。主版本号1,次版本号0,内部版本号7,修订号(专用号)18914,即1.0.7.18914。
检索版本号。使用system.Reflection空间的AssenblyName类的Version属性,这属性返回一个实例,实例使用4个属性,返回版本号的4个部分。Version v = system.Reflection.Assembly.GetExecutingassembly().getName().version; 用重载的V.Tostring()得到版本号;也可指定磁盘文件名获取版本号。
- 版本兼容性与策略文件
版本号命名通用标准。新的主版本号和次版本号表示,这个新版本与老版本不兼容,例如3.0.0.0与版本2.4.8.1932不兼容,只要在代码中引入了不相容版本,就应该更改主版本号;新的内部版本号表示可能兼容,在引入服务包或较小规模的升级时,应该更改次版本号;新的修订号表示这是应该安装的、与上一版本相容的快速修补项目。
策略文件。asp.net是web.config;应用是myapp.exe.config。可指定替代版本号,用旧版本号对应新版本号。用VS的管理工具插件framework config配置这个文件,配置程序集,选择程序集,输入新旧版本号。
- 使用全局程序集缓存
全局程序集类似全局变量,可供多个应用程序使用。
把程序集部署成全局程序集的过程。管理工具,framework configuration,程序集缓存,添加。
- 查找程序集
由4处决定使用哪个版本的程序集。应用最初指定的版本;应用的策略文件重写版本信息;为所有应用重写的发行者策略文件;系统范围内的管理员策略文件。
优先级。应用已经使用这个程序集,继续使用已使用的版本;如果程序集在全局程序集缓存,使用全局的;应用的策略文件里<codebase>指定的程序集。