使用C#2.0命令行编译器.docx_第1页
使用C#2.0命令行编译器.docx_第2页
使用C#2.0命令行编译器.docx_第3页
使用C#2.0命令行编译器.docx_第4页
使用C#2.0命令行编译器.docx_第5页
已阅读5页,还剩22页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

使用 C# 2.0 命令行编译器发布日期 : 12/22/2004 | 更新日期 : 12/22/2004Andrew W. Troelsen,Microsoft MVPIntertech Training摘要:本文分析了使用 C# 命令行编译器 csc.exe 生成应用程序的过程。同时,还将向读者介绍很多为 C# 2.0 独有的编译器选项,例如,extended/reference 标志和强名称支持。阅读完本文的内容之后,您将能够轻松地在没有向导的环境中生成单文件程序集和多文件程序集。 适用于:Microsoft Visual C# 2.0注 本文假定您熟悉 C# 编程语言和 .NET Framework 的结构。体验一下使用命令行工具的感觉还将证明很有帮助。 下载 CSCSample.msi 文件。本页内容scsc.exe 带来的乐趣C# 编译器选项概览配置环境变量命令行基础知识用于指定输入和控制输出的选项编译 .NET 代码库使用 C# 响应文件使用 /reference 引用外部程序集理解 C# 2.0 引用别名使用 /addmodule 生成多文件程序集创建 Windows 窗体应用程序通过 csc.exe 使用资源使用 /define 定义预处理器符号csc.exe 的以调试为中心的选项杂项小结scsc.exe 带来的乐趣几乎没有人会否认集成开发环境 (IDE)(例如,Visual Studio 2005 和 Visual C# Express 2005)所提供的能使编程工作变得相当简单的诸多功能。但是,实际上 IDE 自己通常不能提供对基础编译器的所有方面的访问。例如,Visual Studio 2005 不支持生成多文件程序集。 此外,了解在命令行编译代码的过程,对于具有以下特征的用户可能有用: 偏爱最简单的生成 .NET Framework 应用程序的方法。 希望揭开 IDE 处理源代码文件的方法的秘密。 希望利用 .NET 生成实用工具,例如,nant 或 msbuild。 没有集成开发环境,例如,Visual Studio(但实际上具有免费提供的 .NET Framework SDK)。 正在基于 Unix的系统(在该系统中,命令行是必须使用的工具)上使用 .NET Framework,并且希望更好地了解 Mono 和/或 Portable .NET ECMA 兼容 C# 编译器。 正在研究当前未集成到 Visual Studio 中的备选 .NET 编程语言。 只是希望扩展他们的 C# 编程语言知识。 如果您属于上面所述的这些用户,那么就忠实于自己的选择并继续读下去吧。返回页首C# 编译器选项概览C# 编译器 csc.exe 提供了大量用于对创建 .NET 程序集的方式进行控制的选项。站在一个较高层次来看,命令行选项属于下列八个类别之一(表 1)。表 1. csc.exe 提供的标记的类别C# 编译器类别定义输出文件用于控制所生成的程序集的格式、可选的 XML 文档文件和强名称信息的选项。输入文件使用户可以指定输入文件和引用的程序集的选项。资源用于将任何必需的资源(例如,图标和字符串表)嵌入到程序集中的选项。代码生成这些选项控制调试符号的生成。错误和警告控制编译器处理源代码错误/警告的方式。语言启用/禁用 C# 语言功能(例如,不安全代码)以及条件编译符号的定义。杂项该类别的最有趣的选项使您可以指定 csc.exe 响应文件。高级该类别指定一些更加深奥并且通常不太重要的编译器选项。注 1.0 和 1.1 版本的 C# 编译器中存在的 /incremental 标志现在已过时。 在阅读本文的过程中,您将了解每个编译器类别中存在的核心 标志(最重要的词是核心)。对于大多数开发方案,可以安全地忽略 C# 编译器的很多高级选项。如果您需要有关本文未予讨论的 csc.exe 功能的详细信息,请尽管放心,您可以参阅 Microsoft Visual Studio 2005 文档帮助系统(只须从“Search”选项卡中搜索“csc.exe”并深入查阅)。 注 MSDN 文档也会对您也很所帮助,因为它描述了如何在 Visual Studio(如果可用)内部设置 csc.exe 的特定选项。返回页首配置环境变量在使用任何 .NET SDK 命令行工具(包括 C# 编译器)之前,需要配置开发计算机以识别它们的存在。最简单的方法是使用 Start | All Programs | Visual Studio 2005 | Visual Studio Tools 菜单选项,启动预配置的 Visual Studio 命令提示。这一特定的控制台能够自动初始化必要的环境变量,而无须您执行任何操作。(Visual Studio .NET 2003 用户需要启动他们各自的命令提示)。 注 如果您没有 Visual Studio,但是已经安装了 .NET Framework SDK,则可以从 Start | All Programs | Microsoft .NET Framework SDK 2.0 菜单选项启动预配置的命令提示。如果您希望从任意的 命令提示使用 .NET 命令行工具,则需要手动更新计算机的 Path 变量。做法是,请右键单击桌面上的 My Computer 图标并选择 Properties 菜单选项。从出现的对话框中,单击位于 Advanced 选项卡下面的 Environment Variables 按钮。从出现的对话框中,在 System 变量列表框中的当前 Path 变量的结尾添加以下目录清单(请注意,必须用分号分隔各个条目):C:WindowsMicrosoft.NETFrameworkv2.0.40607C:Program FilesMicrosoft Visual Studio 8SDKv2.0Bin注 上面的列表指向我的当前 .NET 2.0 测试版的路径。您的路径可能因 Visual Studio 和/或 .NET SDK 的安装和版本的不同而略有不同,因此请确保执行完整性检查。 在更新 Path 变量之后,请立即关闭所有对话框和当前打开的任何 Console 窗口,以便提交设置。您现在应当能够从任何命令提示执行 csc.exe 和其他 .NET 工具了。要进行测试,请输入以下命令:csc -?ildasm -?如果您看到有大量信息显示出来,那么您就可以继续了。 返回页首命令行基础知识已经能够熟练地在命令行工作的用户在使用 csc.exe 时不会有任何问题,因而可以跳到下一节。但是,如果您使用命令行的次数很有限,那么请让我说明一些基本的详细信息,以便进行必要的准备。 首先,可以使用反斜杠或单个短划线指定 csc.exe 的选项。其次,在 / 或 - 以及随后的标志之间具有额外的空格是非法 的。因此,“-help”是完全正确,而“- help”就行不通了。为了加以说明,让我们使用 help 标志检查完整的命令行选项集:csc helpcsc /help如果一切正常,则您应当看到所有可能的标志,如图 1 所示。图 1. 帮助标志很多选项都提供了简写表示法,以便为您节省一些键入时间。假设 help 标志的简写表示法是 ?,则您可以如下所示列出 csc.exe 的选项:csc ?csc /?很多选项都需要附加的修饰,例如,目录路径和文件名。这种性质的标志使用冒号将标志与它的修饰分隔开来。例如,/reference 选项要求将 .NET 程序集的名称包括在程序集清单中: csc /reference:MyLibrary.dll .其他标志在性质上是二元 的,因为它们或者被启用 (+),或者被禁用 (-)。二元标志总是默认为它们的禁用状态,因此您通常只需要使用加号标记。例如,要将所有编译警告都视为错误,可以启用 warnaserror 标志: csc /warnaserror+ .标志的顺序无关紧要,但是在指定输入文件集合之前,必须列出所有标志的集合。另外值得说明的是,在修饰和它的关联数据之间具有额外的空格是非法 的。例如,请使用 /reference:MyLibrary.dll,而不要使用 /reference:MyLibrary.dll。返回页首用于指定输入和控制输出的选项我们将要分析的第一组命令行选项用于指定编译器输入(表 2)和控制得到的输出(表 3)。请注意,下面的表还标记了特定于 C# 2.0 的选项和任何可用的简写表示法。 表 2. csc.exe 的以输入为中心的选项输入标志定义是否特定于 C# 2.0?/recurse通知 csc.exe 编译位于项目的子目录结构中的 C# 文件。该标志支持通配符语法。否/reference (/r)用于指定要在当前编译中引用的外部程序集。否,但是 2.0 编译器提供了别名变体。/addmodule用于指定要包括在多文件程序集中的模块。否表 3. csc.exe 的以输出为中心的选项输出标志定义是否特定于 C# 2.0?/out指定要生成的程序集的名称。如果省略该标志,则输出文件的名称基于初始输入文件的名称(对于 *.dll 程序集而言)或定义 Main() 方法的类的名称(对于 *.exe 程序集而言)。否/target (/t)指定要创建的程序集的文件格式。否/doc用于生成 XML 文档文件。否/delaysign使您可以使用强名称的延迟签名生成程序集。是/keyfile指定用于对程序集进行强命名的 *.snk 文件的路径。是/keycontainer指定包含 *.snk 文件的容器的名称。是/platform指定必须存在以便承载程序集的 CPU(x86、Itanium、x64 或 anycpu)。默认为 anycpu。是也许用途最多的输入/输出选项是 /target。该标志通过使用附加的修饰(表 4)告诉编译器您对生成哪个类型的 .NET 程序集感兴趣。表 4. /target 标志的变体目标修饰定义/target:exe创建基于控制台的程序集。如果未指定 /target 选项,则这是默认选项。/target:winexe创建基于 Windows 窗体的可执行程序集。尽管您可以使用 /target:exe 创建 Windows 窗体应用程序,但控制台窗口将在主窗体的后台隐现。/target:library用于生成 .NET 代码库 (*.dll)。/target:module创建将成为多文件程序集的一部分的模块。返回页首编译 .NET 代码库为了说明使用 csc.exe 的输入/输出选项的过程,我们将创建一个强命名的单文件程序集 (MyCodeLibrary.dll),以定义一个名为 SimpleType 的类类型。为了展示 /doc 选项的作用,我们还将生成一个 XML 文档文件。 首先,请在驱动器 C 上创建一个名为 MyCSharpCode 的新文件夹。在该文件夹中,创建一个名为 MyCodeLibrary 的子目录。使用您选择的文本编辑器(notepad.exe 就完全合乎需要)输入以下代码,并将该文件保存为刚刚创建的 C:MyCSharpCodeMyCodeLibrary 目录中的 simpleType.cs。/ simpleType.csusing System;namespace MyCodeLibrary / / Simple utility type. / public class SimpleType / / Print out select environment information / public static void DisplayEnvironment() Console.WriteLine(Location of this program: 0, Environment.CurrentDirectory); Console.WriteLine(Name of machine: 0, Environment.MachineName); Console.WriteLine(OS of machine: 0, Environment.OSVersion); Console.WriteLine(Version of .NET: 0, Environment.Version); 现在,打开命令提示,并且使用 cd(更改目录)命令导航到 simpleType.cs 文件的位置 (C:MyCSharpCodeMyCodeLibrary): cd MyCSharpCodeMyCodeLibrary或cd C:MyCSharpCodeMyCodeLibrary要将该源代码文件编译为名为 MyCodeLibrary.dll 的单文件程序集,请指定以下命令集:csc /t:library /out:MyCodeLibrary.dll simpleType.cs此时,您应当在应用程序目录中具有一个全新的 .NET 代码库,如图 2 所示。 图 2. 新的 .NET 代码库当在命令行编译多个 C# 文件时,可以分别列出每个文件 如果您希望编译包含在单个目录中的 C# 文件的子集,则这可能有所帮助。假设我们已经创建了另外一个名为 asmInfo.cs 的 C# 代码文件(保存在同一目录中),它定义了下列程序集级别属性以描述我们的代码库:/ asmInfo.csusing System;using System.Reflection;/ A few assembly level attributes.assembly:AssemblyVersion()assembly:AssemblyDescription(Just an example library)assembly:AssemblyCompany(Intertech Training)要只编译 simpleType.cs 和 asmInfo.cs 文件,请键入:csc /t:library /out:MyCodeLibrary.dll simpleType.cs asmInfo.cs正如您可能希望的那样,csc.exe 支持通配符表示法。因而,要编译单个目录中的所有文件,请仅将 *.cs 指定为输入选项:csc /t:library /out:MyCodeLibrary.dll *.cs使用 /recurse 指定子目录在创建应用程序时,您肯定喜欢为您的项目创建逻辑目录结构。您可以通过将代码文件放到特定的子目录(Core、AsmInfo、MenuSystem 等等)中对它们进行组织,而不是将多达 25 个文件转储到名为 myApp 的单个目录中。尽管我们的当前示例只包含几个文件,但假设您将 AsmInfo.cs 文件放到一个名为 AsmInfo 的新的子目录(如图 3 所示)中。图 3. 新的 AsmInfo 子目录要告诉 C# 编译器编译位于根目录以及 AsmInfo 子目录中的所有 C# 文件,请使用 /recurse 选项:csc /t:library /out:MyCodeLibrary.dll /recurse:AsmInfo /doc:myDoc.xml *.cs这里,/recurse 已经用特定子目录的名称限定。要指定多个子目录,我们可以再次使用通配符语法。如果我们要将 simpleType.cs 文件移到一个新的名为 Core 的子目录中,则我们可以用以下命令集编译所有子目录中的所有 C# 文件:csc /t:library /out:MyCodeLibrary.dll /recurse:*.cs 在任何一种情况下,输出都是相同的。 使用 /doc 生成 XML 文档文件SimpleType 类已经配备了各种 XML 元素。就像您很可能知道的那样,C# 编译器将使用这些带有三条斜杠的代码注释生成 XML 文档文件。要告诉 csc.exe 创建这样的文件,必须提供 /doc 选项,并且用要生成的文件的名称修饰它:csc /t:library /out:MyCodeLibrary.dll /recurse:*.cs /doc:myDoc.xml在应用程序目录中,您现在应当看到一个名为 myDoc.xml 的新文件。如果您打开该文件,则会发现您的类型以 XML 的形式进行了说明,如图 5 所示。图 5. XML 形式的类型文档注 如果您希望了解 C# XML 代码注释的详细信息,则请参阅文章 XML Comments Let You Build Documentation Directly From Your Visual Studio .NET Source Files。使用 /keyfile 建立强名称当前示例的最后一项任务是为我们的程序集分配一个强名称。在 .NET 1.1 下,创建强命名程序集需要使用 AssemblyKeyFile 属性。尽管这样做就很好了,但 C# 2.0 编译器现在提供了 /keyfile 标志,以指定强名称密钥文件 (*.snk) 的位置。 在驱动器 C 上创建一个名为 MyKeyPair 的新文件夹,然后使用命令提示更改至该目录。接下来,使用 sn.exe 实用工具的 “k 选项创建一个名为 myKeyPair.snk 的新密钥对。sn -k myKeyPair.snk要使用 csc.exe 对 MyCodeLibrary.dll 进行强命名,请发出以下命令集:csc /t:library /out:MyCodeLibrary.dll /recurse:*.cs /doc:myDoc.xml /keyfile:C:MyKeyPairmyKeypair.snk要验证该程序集的确具有强名称,请使用安全实用工具 (secutil.exe) 和 “s 选项显示强名称信息:secutil /sMyCodeLibrary.dll您应当发现,程序集清单中记录的公钥值被显示为如图 6 所示的输出。 图 6. 公钥值的输出C# 2.0 编译器确实还有其他一些以强名称为中心的标志(/delaysign 和 /keycontainer),您可能希望在空闲时加以研究。特别地,如果您希望启用延迟签名,则请使用 /delaysign 选项。 返回页首使用 C# 响应文件尽管通过命令行工作时可以体验到其与生俱来的优势,但没有人能够否认键入数十个编译器选项可能导致手指抽筋和录入错误。为了有助于减轻这两个问题,C# 编译器支持使用响应文件。 注 所有命令提示都允许您使用 Up 和 Down 箭头键遍历以前的命令。 响应文件(它们按照约定采用 *.rsp 文件扩展名)包含您希望供给到 csc.exe 中的所有选项。在创建了该文件以后,您就可以将它的名称指定为 C# 编译器的唯一选项。为了便于说明,下面提供了一个将用于生成 MyCodeLibrary.dll 的响应文件(请注意,您可以使用 # 符号指定注释)。# MyCodeLibraryArgs.rsp# These are the options used# to compile MyCodeLibrary.dll# Output target and name./t:library /out:MyCodeLibrary.dll # Location of C# files. /recurse:*.cs # Give me an XML doc./doc:myDoc.xml # Give me a strong name as well. /keyfile:C:MyKeyPairmyKeypair.snk给定该文件以后,您现在就可以使用 选项指定 MyCodeLibraryArgs.rsp 了:csc MyCodeLibraryArgs.rsp 如果您愿意,则可以指定多个响应文件:csc MyCodeLibraryArgs.rsp MoreArgs.rsp EvenMoreArgs.rsp请记住,按照遇到的顺序对响应文件进行处理。因此,以前的文件中的设置可能被以后的文件中的设置重写。 默认的响应文件和 /noconfig 选项最后,请记住有一个默认的响应文件 csc.rsp,它由 csc.exe 在每次编译期间自动处理。如果您分析该文件(它与 csc.exe 本身位于相同的文件夹中)的内容,则您将只是发现一组经常引用的程序集(System.Windows.Forms.dll、System.Data.dll 等等)。 在您希望禁止包括 csc.rsp 的极少数的场合中,您可以指定 /noconfig 标志:csc /noconfig MyCodeLibraryArgs.rsp注 如果您引用程序集,而实际上并不使用它,则它将不会在程序集清单中列出。因此,请不要担心代码膨胀问题,因为它们根本不存在。返回页首使用 /reference 引用外部程序集此时,我们已经使用命令行编译器创建了具有强名称(并且进行了说明)的单文件代码库。现在,我们需要一个客户端应用程序以便使用它。请在 C:MyCSharpCode 中创建一个名为 MyClient 的新文件夹。在该文件夹中,创建一个新的 C# 代码文件 (simpleTypeClient.cs),该文件从程序的入口点调用静态的 SimpleType.DisplayEnvironment() 方法:/ simpleTypeClient.csusing System;/ Namespace in MyCodeLibrary.dllusing MyCodeLibrary; namespace MyClientApp public class MyApp public static void Main() SimpleType.DisplayEnvironment(); Console.ReadLine(); 因为我们的客户端应用程序要使用 MyCodeLibrary.dll,所以我们需要使用 /reference(或只是使用 /r)选项。该标志很灵活,因为您可以指定所讨论的 *dll 的完整路径,如下所示:csc /t:exe /r:C:MyCSharpCodeMyCodeLibraryMyCodeLibrary.dll *.cs或者,如果私有程序集的副本与输入文件位于相同的文件夹中,则可以只指定程序集名称:csc /t:exe /r:MyCodeLibrary.dll *.cs请注意,我没有指定 /out 选项。给定该条件,csc.exe 基于我们的初始输入文件 (simpleTypeClient.cs) 创建了一个名称。此外,已知 /target 的默认行为是生成基于控制台的应用程序,所以 /t:exe 参数是可选的。 在任何情况下,因为 MyCodeLibrary.dll 是私有程序集,所以您需要将该库的一个副本放到 MyClient 目录中。在您完成该工作以后,您就能够执行 simpleTypeClient.exe 应用程序。图 7 显示了可能的测试运行。图 7. 可能的测试运行输出注 请回忆一下这个问题,不必将具有强名称的程序集部署到全局程序集缓存 (GAC) 中。实际上,因为强名称具有天然的安全性方面的好处,所以向每个程序集(无论共享与否)提强名称是一种 .NET 最佳策略。 引用多个外部程序集如果您希望在命令行引用大量程序集,则可以指定多个 /reference 选项。为了说明这一点,假设我们的客户端应用程序需要使用包含在名为 NewLib.dll 的库中的类型:csc /t:exe /r:MyCodeLibrary.dll /r:NewLib.dll *.cs作为一种稍微简单一些的替代方法,您可以使用单个 /reference 选项,并且使用分号分隔的列表指定每个程序集:csc /t:exe /r:MyCodeLibrary.dl;NewLib.dll *.cs当然,在创作 C# 响应文件时使用相同的语法。 关于 /lib 的简短说明在查看 C# 2.0 程序集别名的作用之前,请允许我对 /lib 标志加以简短说明。该选项可用于将包含由 /reference 选项指定的程序集的目录告诉给 csc.exe。为了进行说明,假设您具有三个位于驱动器 C 的根目录中的 *.dll 程序集。要指示 csc.exe 在 C: 下查找 asm1.dll、asm2.dll 和 asm3.dll,需要发出以下命令集:csc /lib:c: /reference:asm1.dll;asm2.dll;asm3.dll *.cs 如果您未使用 /lib,则需要将这三个 .NET 代码库手动复制到包含输入文件的目录中。还请注意,如果在给定的命令集中多次发出 /lib 标志,则结果将累积起来。 返回页首理解 C# 2.0 引用别名关于 /reference 选项需要进行的最后一点说明是,在 C# 2.0 中,现在可以为引用的程序集创建别名。通过该功能,可以解决在唯一命名的程序集中包含的名称完全相同的类型之间存在的名称冲突问题。 为了说明该功能的实用性,请在 C:MyCSharpCode 目录中创建一个名为 MyCodeLibrary2 的新文件夹。将现有的 simpleType.cs 和 AsmInfo.cs 文件的副本放到新目录中。现在,向 SimpleType 中添加一个能够显示客户端提供的字符串的新方法:/ / Display a user supplied message./ public static void PrintMessage(string msg) Console.WriteLine(You said: 0, msg);编译这些文件,以创建一个名为 MyCodeLibrary2.dll 的新程序集,如下所示:csc /t:library /out:MyCodeLibrary2.dll *.cs最后,将这一新代码库的副本放到 MyClient 文件夹(图 8)中。图 8. MyClient 文件夹中的新代码现在,如果我们的当前客户端程序希望引用 MyCodeLibrary.dll 以及 MyCodeLibrary2.dll,则我们执行以下操作:csc /t:exe /r:MyCodeLibrary.dll;MyCodeLibrary2.dll *.cs编译器告诉我们,我们已经引入了名称冲突,因为这两个程序集都定义了一个名为 SimpleType 的类:simpleTypeClient.cs(13,7): error CS0433: The type MyCodeLibrary.SimpleType exists in both c:MyCSharpCodeMyClientMyCodeLibrary.dll and c:MyCSharpCodeMyClientMyCodeLibrary2.dll乍看起来,您可能认为可以通过在客户端代码中使用完全限定名称来修复该问题。但是,这样做无法纠正该问题,因为这两个程序集定义了相同的完全限定名称 (MyCodeLibrary。SimpleType)。 使用 /reference 标志的新别名选项,我们可以为引用的每个代码库生成唯一的名称。在我们这样做之后,我们就可以更新客户端代码,以便将某个类型与特定的程序集相关联。 第一步是修改 simpleTypeClient.cs 文件,以使用我们将通过新的 extern alias 语法在命令行指定的别名:/ Extern alias statements must be / listed before all other code!extern alias ST1; extern alias ST2;using System;namespace MyClientApp public class MyApp public static void Main() / Bind assembly to type using the : operator. ST1:MyCodeLibrary.SimpleType.DisplayEnvironment(); ST2:MyCodeLibrary.SimpleType.PrintMessage(Hello!); Console.ReadLine(); 请注意,我们已经使用 C# 2.0 extern alias 语句捕获了在命令行定义的别名。这里,ST1(简单类型 1)是为 MyCodeLibrary.dll 定义的别名,而 ST2 是 MyCodeLibrary2.dll 的别名:csc /r:ST1=MyCodeLibrary.dll /r:ST2=MyCodeLibrary2.dll *.cs 给定这些别名,请注意 Main() 方法如何使用 C# 2.0 范围解析运算符 (:) 将程序集别名绑定到类型本身:/ This says I want the MyCodeLibrary.SimpleType class / that is defined in MyCodeLibrary.dll.ST1:MyCodeLibrary.SimpleType.DisplayEnvironment();进而,/reference 选项的这一变体可以提供一种避免名称冲突(当两个具有唯一名称的程序集包含名称完全相同的类型时发生)的方式。 返回页首使用 /addmodule 生成多文件程序集就像您可能已经知道的那样,多文件程序集提供了一种将单个 .NET 二进制文件分解为多个较小的小文件的方式,这在远程下载 .NET 模块时证明很有帮助。多文件程序集的最终效果是让一组文件像一个单独引用和进行版本控制的单元那样工作。 多文件程序集包含一个主 *.dll,它包含程序集清单。该多文件程序集的其他模块(按照约定,它们采用 *.netmodule 文件扩展名)被记录在主模块的清单中,并且由 CLR 按需加载。迄今为止,生成多文件程序集的唯一方式是使用命令行编译器。 为了说明该过程,请在 C:MyCSharpCode 目录中创建一个名为 MultiFileAsm 的新子目录。我们的目标是创建一个名为 AirVehicles 的多文件程序集。主模块 (Airvehicles.dll) 将包含单个名为 Helicopter 的类类型(稍后定义)。程序集清单编录了一个附加模块 (module),该模块定义了一个名为 UFO 的类类型:/ ufo.csusing System;using System.Windows.Forms;namespace AirVehicles public class UFO public void AbductHuman() MessageBox.Show(Resistance is futile); 要将 ufo.cs 编译为 .NET 模块,请指定 /t:module 作为目标类型,这会自动遵循 *.netmodule 命名约定(请回想一下,默认的响应文件自动引用 System.Windows.Forms.dll,因此我们不需要显式引用该库):csc /t:module ufo.cs如果您要将 module 加载到 ildasm.exe 中,您会发现一个记载了该模块的名称和外部引用程序集的模块级别清单(请注意,*.netmodules 没有指定版本号,因为那是主模块的工作):.assembly extern mscorlib.assembly extern System.Windows.Forms.module module现在,请创建一个名为 helicopter.cs 的新文件,该文件将用于编译主模块 Airvehicles.dll:/ helicopter.csusing System;using System.Windows.Forms;namespace AirVehicles public class Helicopter public void TakeOff() MessageBox.Show(Helicopter taking off!); 假设 Airvehicles.dll 是该多文件程序集的主模块,则您将需要指定 /t:library 标志。但是,因为您还希望将 module 二进制文件编码到程序集清单中,所以您还必须指定 /addmodule 选项:csc /t:library /addmodule:module /out:airvehicles.dll helicopter.cs如果您要分析 airvehicles.dll 二进制文件内部包含的程序集级别清单(使用 ildasm.exe),则会发现 module 确实是使用 .file CIL 指令记录的:.assembly airvehicles.file module多文件程序集的使用者可以较少关心他们要引用的程序集由大量二进制文件组成这一事实。实际上,在句法上将看起来与使用单文件程序集的行为完全相同。为了使本文变得更有趣一些,让我们创建一个基于 Windows 窗体的客户端应用程序。返回页首创建 Windows 窗体应用程序我们的下一个示例项目将是一个使用 airvehicles.dll多文件程序集的 Windows 窗体应用程序。在 C:MyCSharpCode 目录中创建一个名为 WinFormClient 的新的子目录。创建一个派生自 Form 的类,该类定义了单个 Button 类型,当它被单击时,将创建 Helicopter 和 UFO 类型,并且调用它们的成员:using System;using System.Windows.Forms;using AirVehicles;public class MyForm : Form private Button btnUseVehicles = new Button(); public MyForm() this.Text = My Multifile Asm Client; btnUseVehicles.Text = Click Me; btnUseVehicles.Width = 100; btnUseVehicles.Height = 100; btnUseVehicles.Top = 10; btnUseVehicles.Left = 10; btnUseVehicles.Click += new EventHandler(btnUseVehicles_Click); this.Controls.Add(btnUseVehicles); private void btnUseVehicles_Click(object o, EventArgs e) Helicopter h = new Helicopter(); h.TakeOff(); UFO u = new UFO(); u.AbductHuman(); private static void Main() Application.Run(new MyForm(); 注 在继续操作之前,请确保将 airvehicals.dll 和 module 二进制文件复制到 WinFormClient 目录中。 要将该应用程序编译为 Windows 窗体可执行文件,请确保指定 winexe 作为 /target 标志的修饰。请注意,在引用多文件程序集时,只须指定主模块的名称:csc /t:winexe /r:airvehicles.dll *.cs在运行您的程序并单击按钮之后,您就应当看到按照预期显示的每个消息框。图 9 显示了我创建的一个消息框。图 9. 示例消息框返回页首通过 csc.exe 使用资源下一个议程是分析如何使用 csc.exe 将资源(例如,字符串表或图像文件)嵌入到 .NET 程序集中。首先,可以使用 /win32Icon 选项指定 Win32 *.ico 文件的路径。假设您已经将一个名为 HappyDude.ico 的图标文件放到当前 Windows 窗体应用程序的应用程序目录中。要将 HappyDude.ico 设置为可执行文件的图标,请发出以下命令集:csc /t:winexe /win32icon:HappyDude.ico /r:airvehicles.dll *.cs此时,应当更新可执行程序集,如图 10 所示。图 10. 经过更新的可执行程序集除了使用 /win32icon 分配应用程序图标以外,csc.exe 还提供了三个附加的以资源为中心的选项(表 5)。表 5. csc.exe 的以资源为中心的选项csc.exe 的以资源为中心的选项定义/resource将 *.resources 文件内部包含的资源嵌入到当前程序集中。请注意,通过该选项可以“以公共方式”嵌入资源以供所有使用者使用,或者“以私有方式”嵌入资源以便仅供包含程序集使用。/linkresource在程序集清单中记录指向外部资源文件的链接,但实际上并不嵌入资源自身。/win32res使您可以嵌入存在于旧式 *.res 文件中的资源。在我们了解如何将资源嵌入到我们的程序集中以前,请让我对 .NET 平台中的资源的性质进行简短的介绍。正如您可能已经知道的那样,.NET 资源开始时通常呈现为一组被记录为 XML(*.resx 文件)或简单文本 (*.txt) 的名称/值对。该 XML/文本文件随后被转换为等效的二进制文件,它采用 *.resources 文件扩展名。然后,这些二进制文件被嵌入到程序集中并且被记录在清单中。当需要以编程方式从该程序集中读取资源的时候,System.Resources 命名空间会提供很多类型来完成该工作,其中最值得注意的是 ResourceManager 类。 尽管您肯定可以手动创建 *.resx 文件,但您最好使用 resgen.exe 命令行工具(或者,您当然可以使用 Visual Studio .NET 本身)。虽然本文不打算描述 resgen.exe 的全部详细信息,但是让我们演练一个简单的示例。使用 /resource 嵌入资源在 MyCSharpCode 下面创建一个名为 MyResourceApp 的新目录。在该目录中,使用 notepad.exe 创建一个名为 myStrings.txt 的新文件,并且使其包含您选择的一些有趣的名称/值对。例如: # A list of personal data#company=Intertech TraininglastClassTaught=.NET SecuritylastPresentation=SD East Best PracticesfavoriteGameConsole=XBoxfavoriteComic=Cerebus现在,使用命令提示,通过以下命令将 *.txt 文件转换为一个基于 XML 的 *.resx 文件:resgen myStrings.txt myStrings.resx如果您使用 no

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论