学习笔记《.NET框架程序设计(修订版)》--第二章 生成、打包、部署及管理应用程序与类型(2)
2004-12-18
** 2.3 将模块组合为程序集 **
上一节例子里生成的 App.exe 文件是只有一个 PE 文件的程序集( 1.2 中讲到程序集)。程序集总有一个文件(它可以是单独的只保存清单的文件,也可以是普通的一个文件)保存了 **清单( manifest )。 **
** 清单( manifest ) ** 是一组元数据表的集合,其中主要包含了程序集中一部分文件的名称,它还描述了程序集的版本、语言文化、发布者、公有导出类型,以及组成该程序集的所有文件。 CLR 运行程序时总是先加载包含清单元数据表的文件,以此获得程序集的其他文件
1 、引入程序集的概念允许我们分离可重用类型的逻辑表示和物理表示。如,在一个程序里我们可以将各个不同类型分开在几个文件中,不怎么常用的类型甚至是在互联网上,需要时才由程序下载到本地机器上(这个功能的实现在第三章回讲到);
2 、常见的清单元数据表:
AssemblyDef :如果模块是一个程序集则在此表中有一个对应条目。条目包括程序集名称(不含路径和扩展名),版本号,语言文化,一些标记,散列算法,以及发布者的共有密钥;
FileDef :程序集中除清单所在的 PE 文件和资源文件都在此表有一个对应条目;
ManifestResourceDef :程序集包含的每个资源在此表中一个对应条目。如果这个资源不是单独的一个文件,而是嵌入 PE 文件的一个流,则条目包括一个标识资源流在 PE 文件中的起始偏移;
ExportedTypeDef :程序集中所有的 PE 模块导出的每个共有类型在此表有一对应条目。条目包括类型名称,一个 FileDef 表中的索引(实现该类型的那个文件),和一个 TypeDef 表中的索引;
AssemblyRef :程序集所有文件应用的其他程序集在此表中有一对应条目。
3 、在 2.2 的编译命令中, /t[arget]:exe 、 /t[arget]:winexe 、 /t[arget]:library 是让编译器生成一个程序集,用 /t[arget]:module 可让编译器生成一个不包括清单元数据的 PE 文件,它总是一个 DLL 文件,以 .netmodule 为扩展名。
例子:
有两个源代码文件: RUT.sc ,其中包含着很少使用的类型; FUT.cs ,其中包含经常使用的类型;
a 、将 RUT.sc 文件编译为一个模块 ( 这样,如果用户从不访问它包含类型,程序集运行时将不加载它 ) : csc /t:module RUT.cs
b 、将 FUT.cs 编译也编译为一个模块,且作为程序集清单的保存者(这样就是生成了一个程序集,它将代表整个程序集): csc /out:DifallTypes.dll /t:library /addmodule:RUT.netmodule FUT.cs ;
上述例子生成的程序集包括了两个文件: RUT.netmodule 、 DifallTypes.dll ,其中后者包含了清单元数据表。若运行该程序, CLR 会先从后者的清单元数据表中了解程序集的相关信息。
** 2.3.1 使用 Visual Studio .NET IDE 为项目添加程序集引用 **
在『解决方案资源管理器』――『添加引用』菜单中实现
** 2.3.2 使用程序集连接器( Assembly Linker , AL.exe ) **
用这个工具也可以生成程序集 , 它可以创建包含不同编译器生成的模块的程序集。
上面的例子可以这样做:
csc /t:module RUT.cs
csc /t:module FUT.cs
al /out:DifallTupes.dll /t:library FUT.netmodule RUT.netmodule
这时生成的程序集包含了三个文件: DifallTupes.dll 、 FUT.netmodule 、 RUT.netmodule ;第一个文件仅包含了清单信息,后两者为模块 PE 文件。
** 2.3.3 在程序集中包含资源文件 **
1 、在 AL.exe 来创建程序集时,可以用 /embed[resource] 将资源文件添加到程序集里,将其嵌入到一个 PE 文件中; /link[resource] 则将一个资源文件作为单独的文件加入到程序集中。
2 、在 AL.exe 或 CSC.exe 也可以用 /win32res 标准 Win32 资源嵌入到程序集中,用 /win32icon 标准 Win32 图标资源嵌入到程序集中
** 2.4 程序集版本资源信息 **
用 AL.exe 和 CSC.exe 产生 PE 文件时,它们会将一个标准 Win32 版本资源嵌入到 PE 文件里(使它包括如程序版本号、发布者、公司说明等等信息)。 AL.exe 可以用命令开关来代替系统生成的版本信息, CSC.exe 则不行。
** 2.4.1 版本号 **
版本号包括由点号分开的四部分:主版本号、次版本号、生成版本号和修订版本号;前两个组成了“面向共众”的版本部分,后两部分是公司内部使用的。
** 2.5 语言文化 **
它也是程序集标识的一部分,如你有一个程序集,可以是专为德语的版本、也可以是瑞士德语版本等等。没有指定语言文化的程序集是语言文化中性( culture neutral )的程序集。
** 2.6 简单应用程序部署(私有部署程序集) **
和应用程序部署在同一个目录下的程序集称作 私有部署程序集, 这样的程序集不被其他应用程序共享。删除时简单地将目录删除即可。
** 2.7 简单管理控制(配置) **
为了对一个应用程序进行管理控制,我们可以在应用程序的目录下安放一个配置文件。安装程序则应该将该配置文件安装在应用程序的基目录下。 CLR 通过解析该文件来改变其定位和加载程序集时的策略。它包含的都是 XML 数据。
1 、例子:
2.3.2 中的程序集文件部署在
AppDir 目录下,该目录下包含:
App.exe
App.exe.config ( 即配置文件,它的名称必须时应用程序的名称加一个 .config 扩展名 )
AppDir 下有一子目录 AuxFiles ,包含:
DifallTupes.dll
FUT.netmodule
RUT.netmodule
这里, DifallTupes.dll 文件不在应用程序基目录下, CLR 运行程序时无法加载,此时我们就需要一个这样的配置文件:
1<configuration>
2<runtime>
3<assemblybinding xmlns="”urn:schemas-microsoft-com:asm.vl”">
4<probing privatepath="”AuxFiles”"></probing>
5
6< /assemblyBinding >
7
8</assemblybinding></runtime>
9</configuration>
probing 中的 privatePath 属性可以指定多个相对(于应用程序基目录)路径,多个路径之间以分号隔开。
2 、我们可以使用 System.Configuration 命名空间中的类在运行时操作配置文件;
3 、对于不同的应用程序, XML 配置文件的名称和位置也有所不同:
可执行应用程序( EXE ),配置文件必须位于应用程序的基目录中,名字必须是 EXE 文件名加 .config 扩展名;
对于 ASP.NET WEB 窗体和 XML Web 服务应用程序,配置文件必须位于 Web 应用程序的虚拟目录下,且名称总是 Web.config 。子目录也可以包含它们自己的 Web.config 文件,并继承上一目录的配置设置;
对于包含客户方控件、以微软的 IE 浏览器为宿主的程序集, HTML 页面必须包含一个连接标记,并将其中的 rel 属性设置为“ Configuration ”,而将 href 属性设置为配置文件的 URL ,配置文件的名字可以任意。
4 、其实配置文件可以应用于整个机器。当安装》 .NET 框架时,会创建一个 Machine.config 文件。通过修改该文件的配置我们就可以建立起应用于整个机器范围的策略。你所建立的应用于特定应用程序的配置文件中的设置会覆盖该文件的设置。
5 、微软提供了辅助的 GUI 工具帮助我们进行配置文件的设置。使用步骤如下:
“控制面板”——“ Microsoft .NET Framework Configuration ”――“应用程序”――“将应用程序添加到配置中”
关于配置文件在第 3 章中有更多的讨论。
( 今天整理的最长,篇幅最长,花的时间也最长――三个晚上,一到年底就没什么时间座下来认真看书。越看到后面就越觉得这本书确实有很多很有价值的东西,我已经看到第 _ 7 _ _ 章,朋友们如果关心这个笔记的话看到这里应该也会有这种感觉。我觉得我象这本书的推销员,感觉出版社确实可以聘我做半个推销员了 _ )