[From 2.4]C#编译器和程序集链接器(以及一些它们的命令开关)
C#编译器:(用csc命令来使用C#编译器)
程序集链接器(Assembly Linker):(用al命令来使用C#编译器)
除了使用C#编译器,还可以使用”程序集链接器“使用程序AL.exe来创建程序。
1.如果程序集要包含由不同编译器生成的模块(而且这些编译器不支持与C#编译器的/addmodule)。
2.可用AL.exe生成只含资源的程序集,也就是所谓的附属程序集(satellite assembly),它们通常用于本地化。(例子3)
3.能生成EXE文件,或者生成只包含清单(对其他模块中的类型进行描述)的DLL PE文件。(例子4)
C#编译器支持开关:
-
/t[arget]:exe,/t[arget]:winexe,/t[arget]:appcontainerexe,/t[arget]:library或者/t[arget]:winmdobj.所有这些开关都会造成编译器生成含有清单元数据表的PE文件,这些开关分别生成CUI执行体,GUI执行体,Windows Store执行体,类库或者WINMD库。
-
除了这些开关,/t[arget]:module:C#编译器还支持/t[target]:module开关,这个开关指示编译器生成一个不包含清单元数据表的PE文件。这样生成的肯定是一个DLL PE文件。CRL想访问其中的任何类型,必须先将该文件添加到一个程序集中。使用/t:module开关时,C#编译器默认为输出文件使用.netmodule扩展名(例子1)
-
/addmodule:可通过许多方式将模块添加到程序集,如果用C#编译器生成含清单的PE文件,可以使用/addmodule开关。(例子2)
-
/r[eference]:客户端代码必须使用XXX.dll编译器开关生成,才能使用XXX.dll的程序集的类型。
-
/resource(C#编译器独有,相当于al的/embed[resource]):/resource开关将指定的资源文件嵌入最终生辰的程序集PE文件中,并更新ManifestResouceDef表,
-
/linkresouce(C#编译器独有,相当于al的/link[resource]);/linkresouce开关在ManifestResourceDef和FileDef清单表中添加记录项来引用独立存在的资源文件。
AL.exe(程序集链接器)支持:(C#编译器一些支持的AL.exe也支持)
/embed[resource](AL独有):用AL.exe创建程序集时,可用/embed[resource]开关将文件作为资源添加到程序集。该开关获取任意文件,并将文件内容嵌入最终的PE文件。清单的ManifestResourceDef表会更新以反映新资源的存在。
/link[resource](AL独有):它同样获取包含资源的文件,但只是更新清单的ManifestResource和FileDef表以反映新资源的存在,指出资源包含在程序集的哪个文件中。资源文件不会嵌入程序集PE文件中:相反,它保持独立,而且必须和其他程序集文件一起打包和部署。
/main:AL.exe还会生成一个小的全局函数,名为__EntryPoint._实际没有多大用处,开发人员只需知道有这个开关就可以了。(例子4)
/c[ulture]:text开关指定语言文化。例如“en-US”代表英语文化。
/win32res:指定一个.res文件的路径名。(C#编译器和程序集链接器共有)
/win32icon:指定一个.ico文件的路径名。(C#编译器和程序集链接器共有)
例子1:csc /t:module RUT.cs
上述命令行指示C#编译器创建名为RUT.netmodule的文件。这是一个标准的DLL PE文件,但是,CLR不能单独加载它。
例子2:csc /out:MutiFileLibrary.dll /t:library /addmodule:RUT.netmodule FUT.cs
上述命令行指示C#编译器编译FUT.cs来生成MultiFileLibrary.dll。
由于指定了/t:library开关,所以生成的是含有清单元数据表的DLL PE文件,
/addmodule:RUT.netmodule开关告诉编译器RUT.netmodule文件时程序集的一部分,具体的说,/addmodule开关告诉编译器将文件添加到FileDef清单元数据表,并将RUT.netmodule的公开导出类型添加到ExportedTypesDef清单元数据表
例子3:
csc /t:module RUT.cs
csc /t:module FUT.cs
al /out:MultiFileLibrary.dll /t:library
RUT.netmodule FUT.netmodule
这个例子首先创建两个单独的模块即RUT.netmodule和FUT.netmodule。
然后生成第三个文件MultiFileLibrary.dll,它是DLL PE文件(因为使用了/t[arget]:library开关),不包含IL代码,但包含清单元数据表,清单元数据表指出RUT.netmodule和FUT.netmodule是程序集的一部分。最终的程序集由三个文件构成:MultiFileLibrary.dll,RUT.netmodule和FUT.netmodule。程序集链接器不能将多个文件合并成一个文件。
例子4:
csc /t:module /r:MultiFileLibrary.dll Program.cs
al /out:Program.exe /t:exe /main:Program.Main
Program.netmodule
第一行将Program.cs文件生成为Program.netmodule文件。第二行生成包含清单元数据表的Program.exe PE文件。此外,由于使用了/main:Program.Main命令行开关,AL.exe还会生成一个小的全局函数名为__EntryPoint。(这个函数只是调用了一下在Program.netModule文件定义的Program类型中包含Main方法。并没有什么意义,开发者只需要知道由这个开关就可以了。)