使用.NET命令行编译器编译项目(如ASP.NET、C#等)(8)

在我们了解如何将资源嵌入到我们的程序集中以前,请让我对 .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 Training lastClassTaught=.NET Security lastPresentation=SD East Best Practices favoriteGameConsole=XBox favoriteComic=Cerebus

现在,使用命令提示,通过以下命令将 *.txt 文件转换为一个基于 XML 的 *.resx 文件:

resgen myStrings.txt myStrings.resx

如果您使用 notepad.exe 打开该文件,则会找到许多描述名称/值对的 XML 元素,例如:

<data> <value xml:space="preserve">Intertech Training</value> </data> <data> <value xml:space="preserve">.NET Security</value> </data>

要将该 *.resx 文件转换为二进制的 *.resources 文件,只须将文件扩展名作为 resgen.exe 的参数进行更新:

resgen myStrings.resx myStrings.resources

此时,我们具有了一个名为 myStrings.resources 的二进制资源文件。通过 /resource 标志可以达到使用 csc.exe 将该数据嵌入到 .NET 程序集中的目的。假设我们已经创作了位于 MyResourceApp 目录中的以下 C# 文件 (resApp.cs):

// This simple app reads embedded // resources and displays them to the // console. using System; using System.Resources; using System.Reflection; public class ResApp { private static void Main() { ResourceManager rm = new ResourceManager("myStrings", Assembly.GetExecutingAssembly()); Console.WriteLine("Last taught a {0} class.", rm.GetString("lastClassTaught")); } }

要相对于您的 myStrings.resources 文件编译该程序集,请输入以下命令:

csc /resource:myStrings.resources *.cs

因为我尚未指定 /out 标志,所以在该示例中,我们的可执行文件的名称将基于定义了 Main() 的文件 resApp.exe。如果一切正常,则在执行以后,您应当发现类似于图 11 的输出。

使用.NET命令行编译器编译项目(如ASP.NET、C#等)

图 11. 输出

我希望您能够轻松地使用 csc.exe 和所选的文本编辑器创建单文件和多文件 .NET 程序集(带有资源!)。您已经学习了 csc.exe 的最常见的命令行选项,而本文的其余部分将分析一些不太常用但仍然有帮助的选项。

如果您愿意继续学习,请在 MyCSharpCode 文件夹中创建一个名为 FinalExample 的新目录。


使用 /define 定义预处理器符号

尽管 C# 编译器没有真正预处理代码,但该语言的确允许我们使用类似于 C 的预处理器符号来定义该编译器以及与其进行交互。使用 C# 的 #define 语法,可以创建能够控制应用程序内部的执行路径的标记。

必须在使用任何语句或其他 C# 类型定义之前列出所定义的符号。

为了利用常见的示例,假设您希望定义一个名为 DEBUG 的符号。为此,请创建一个名为 finalEx.cs 的新文件,并将其保存在 MyCSharpCode\FinalExample 目录中:

// Define a 'preprocessor' symbol named DEBUG. #define DEBUG using System; public class FinalExample { public static void Main() { #if DEBUG Console.WriteLine("DEBUG symbol defined"); #else Console.WriteLine("DEBUG not defined"); #endif } }

请注意,在我们使用 #define 定义了符号以后,我们就能够使用 #if、#else 和 #endif 关键字来有条件地检查和响应该符号。如果您现在编译该程序,则应当看到在 finalEx.exe 执行时,消息“DEBUG symbol defined”显示到控制台上:

csc *.cs

但是,如果您注释掉符号定义:

// #define DEBUG

则输出将会像您预料的那样(“DEBUG not defined”)。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wjfzjj.html