第一部分 CLR基础:第2章 生成、打包、部署和管理应用程序及类型

2.1.NET Framework部署目标

Microsoft Windows多年来因不稳定和复杂而口碑不佳。
造成的原因:
1.应用程序都使用来自微软和厂商的动态链接库(dynamic-link library,DLL),可能互相会干扰破坏。
2.安装的复杂性:应用程序安装需要将文件复制到目录、更新注册表、创建快捷方式。不能轻松将应用程序转移到另一天电脑,也无法保证卸载干净。
3.安全性:程序可能后台操作一些用户不希望发生的动作,比如下载,执行危险操作等。

附注:
.NET Framew正尝试解决DLL hell的问题,但目前快捷方式的问题还不能解决。安全性上,.NET Framework包含一个名为“代码访问安全性”(code access security)的安全模式,可以让用户很好的控制应用程序的权限。

 

2.2将类型生成到模块中

简单示例代码:

public sealed class Programe{
  public static void Main(){
    System.Console.WriteLine("Hi");
  }
}


解释:System.Console是微软已经实现好的类型,IL代码存储在MSCorLib.dll文件中。
命令执行:
csc.exe /out.Program.exe /t:exe /r:MSCorLib.dll Program.cs
生成名为Program的
/out:Programe.exe 可执行文件
/t[target]:exe Win32控制台应用程序类型
/r[reference]:MSCorLib.dll开关:告知编译器引用类型的位置,使之能解析。
/t:exe 控制台界面(console user interface,CUI)
/t:winexe图形界面(graphical user interface,GUI)

MSCorLib.dll包含了所有核心类型:Byte,Char,String,Int32等等,C#编译器会自动默认引用。也可以通过/nostdlib开关来禁止引用。
故上面代码可简化为:
csc.exe /out.Program.exe /t:exe Program.cs

另外,/out.Program.exe /t:exe为C#编译器默认设定,继续简化为:
csc.exe Program.cs

生成的Programe.exe文件的实质:
是标准的PE(可移植执行体,Portable Executable)文件。

响应文件:
响应文件是包含一组编译器命令开关的文本文件。执行CSC.exe时,编译器会打开响应文件,使用其中的所有开关。
假如响应文件MyProject.rsp:
/out:MyProject.exe
/target:winexe
让CSC.exe使用这些设置,可以如下调用:
csc.exe @MyProject.rsp CodeFile1.cs CodeFile2.cs

 

2.3元数据概述

托管文件由4部分组成:
1.PE32(+)头:Windows要求的标准信息
2.CLR头:小信息块,需要CLR的模块(托管模块)特有的。
包含:
a.模块生成时面向CLR的主次版本号;
b.一些标志(flag);
c.一个MethodDef token,它指定了模块入口方法(是CUI或GUI执行体);
d.可选的强名称数字签名;
e.模块内部特定元素据表大小和偏移量
3.元数据:是二进制数据块。由几个表构成:定义表、引用表、清单表
4.IL:中间代码

检查托管PE文件的元数据:
ILDasm.exe (IL Disassembler,IL反汇编器)
执行命令:ILDasm Program.exe
视图-元信息-显示(快捷键Ctrl+M)显示具体信息

 

Program.exe包含一个TypeDef,它的名称是Program。这个类型代表一个public sealed类,这个类从System.Object派生的。Program类型还定义了两个方法:Mian和.ctor(构造器,constructor)。

Main是一个public static方法,它的代码是IL代码。Main的返回类型是void,无参数。构造器.ctor是一个public方法,它的代码也是IL代码。构造器的返回类型是void,无参数,还有一个tiis指针,指向调用方法时要构造的对象的内存。

查看Program.exe程序集统计信息:视图-统计

注意:ILDasm.exe有一个bug,不要相信Unaccounted信息。

 

 2.4将模块合并成程序集
Programe.exe文件不仅是含有元数据的PE文件,还是一个程序集(assembly)。
程序集:是一个或多个类型定义文件 + 资源文件
程序集中有一个文件容纳了清单(mainfest,一组元数据表的集合),表中主要包含组成程序集文件的名称、程序集版本、语言文化、发布者、公开导出的类型(public)、构成程序集的所有文件。

CLR操作的是程序集,CLR首先加载“清单”元数据表文件,再根据“清单”获取程序集中其他文件名称。

程序集重要特征:
1.程序集定义了可重用的类型。
2.程序集标记了一个版本号。
3.程序集可以有关联的安全信息。
除了包含清单元素表的那个文件,程序集其他单独文件不具备以上特征。

程序集大多是一个文件构成,也可多个文件构成:含元数据的PE文件+资源文件(如.gif)。
便于理解,可将程序集视为逻辑EXE或DLL。

微软引入“程序集”概念的意义:可重用类型的逻辑表示与物理表示能够区分开。对类型进行划分,形成逻辑分隔,方便取想要的那部分。

使用多文件程序集的理由:
1.单独文件对类型进行划分,方便局部操作。
2.可向程序集中添加资源或数据文件。(可以用AL.exe程序集链接器,使数据文件成为程序集的一部分)。
3.程序集中各个类型可用不同编程语言来实现。(C#,VB等)

程序集是进行重用、版本控制、应用安全性设置的一个基本单元。

为了生成程序集,必须选择一个PE文件作为“清单”的宿主,或者单独创建一个PE文件。
下表总结了一些清单元数据表,它们负责将托管模块装换成程序集。


VS中不能创建多文件程序集,只能使用命令工具。

用命令生成多文件程序集:
RUT.cs 不常用类型
FUT.cs 常用类型
1.将不常用类型编译到一个单独模块中:
csc /t:module RUT.cs  创建名为RUT.netmodule文件,是标准的DLL PE文件,但CLR不能单独加载它

2.将常用类型编译到一个模块中,并作为程序集清单的宿主,来代表整个程序集
csc /out:JeffTypes.dll /t:library /addmodule.RUT.netmodule FUT.cs
上述命令指示C#编译器编译FUT.cs文件生成JeffTypes.dll文件。
指定了/t:library开关,生成的JeffTypes.dll是包含了清单元数据表的DLL PE文件。
/addmodule.RUT.netmodule开关告诉编译器,RUT.netmodule是程序集的一部分,将文件添加到FileDef清单数据表中,并将RUT.netmodule的公开导出类型添加到ExportedTypesDef清单元数据表中。

编译结束生成以下两个文件

RUT.netmodule文件包含IL代码、定义元数据表(描述了RUT.cs定义的类型、方法、字段、属性、事件等)、引用元数据表(描述有RUT.cs定义的类型、方法等)。

JeffTypes.dll是一个独立文件,包含IL代码、定义/引用元数据表、清单元数据表(描述构成程序集的所有文件:JeffTypes.dll文件本身和RUT.netmodule、和导出的public类型)使之成为一个程序集的主模块文件。

 

 2.5程序集版本资源信息
PE文件程序集查看属性。代码调用System.Diagnostics.FileversionInfo的static方法GetVersionInfo来查看。

2.6语言文化
通常用AL.exe工具来生成附属程序集。可以使用/c[culture]:text开关来指定目标文化语言(如,en-US)。

2.7简单应用程序部署(私有部署的程序集)
简单打包部署:程序集文件拷贝到光盘 - 执行批处理程序 - 文件复制到用户硬盘目录 - 点击运行(卸载直接删除文件即可)
VS发布:打开醒目的属性对话框 - “发布”选项卡 - 生成MSI文件 - 复制到网站、FTP服务器或文件路径 - 利用ClickOnce技术
私有部署的程序集:部署到和应用程序相同的目录中的程序集

2.8简单管理控制(配置)
实现对应用程序的管理控制:在应用程序目录中放一个配置文件,配置文件包含的是XML代码,它既能和某个应用程序关联,也能和整个机器关联。

 

 

posted @ 2014-02-17 15:30  IT浪潮之巅  阅读(294)  评论(0)    收藏  举报
   友情链接: 淘宝优惠券