1. Resource Basics
(1) Manifest Resources(资源清单)
资源在编译期间添加到程序集。如果要将资源嵌入到程序集,则必须将文件添加到项目中,文件会自动拷贝到项目文件夹的Resources文件夹中。如果要嵌入到程序集,还需选中文件,修改其属性“生成操作”(Build Action)为“嵌入的资源”,默认为“内容”。
一旦设置为嵌入的资源,则它就会成为资源清单中程序集的一部分。每一程序集,无论是静态的还是动态的,均包含描述该程序集中各元素彼此如何关联的数据集合。程序集清单就包含这些程序集元数据。程序集清单包含指定该程序集的版本要求和安全标识所需的所有元数据,以及定义该程序集的范围和解析对资源和类的引用所需的全部元数据。
(2) Naming Mainfest Resources
要查看一个已经正确嵌入到项目输出程序集中的文件,可以利用SDK工具 ildasm.exe,它其实就是 MSIL 反汇编程序,它能够在你程序集的Mainfest视图里显示所有的嵌入资源。
它在ildasm中显示为 .mresource 入口,资源名称显示格式如下:
defaultNamespace.folderName.fileName
defaultNamespace 可以在项目的属性页面中“应用程序”Tab页面中进行更改。
(3) Loading Mainfest Resources
也通过程序来枚举清单,需要利用到 System.Reflection.Assembly 类的 GetMainifestResourceNames 方法。另外,还可以检索特定类型的程序集,例如 Assembly 类还提供了 GetAssembly、GetCallingAssembly、GetEntryAssembly 和 GetExecutingAssembly 等。
// Get this type's assembly Assembly asm =this.GetType().Assembly; // Enumerate the assembly's manifest resources foreach( string resourceName in asm.GetManifestResourceNames() ){ MessageBox.Show(resourceName); }</div>
Type 为 System.Reflection 功能的根,也是访问元数据的主要方式。使用 Type 的成员获取关于类型声明的信息,如构造函数、方法、字段、属性 (Property) 和类的事件,以及在其中部署该类的模块和程序集。
表示某个类型是唯一的 Type 对象;即,两个 Type 对象引用当且仅当它们表示相同的类型时,才引用相同的对象。这允许使用参考等式来比较 Type 对象。Type 类表示类型声明:类类型、接口类型、数组类型、值类型、枚举类型、类型参数、泛型类型定义,以及开放或封闭构造的泛型类型。Object.GetType 方法返回表示实例类型的 Type 对象。
如果知道资源的名称,则可以通过 Assembly 类的方法 GetManifestResourceStream 方法加载指定的清单资源,资源名称大小写敏感,而且是全称。例如:
// Get this type's assembly Assembly asm =this.GetType().Assembly; // Get the stream that holds the resource // from the "ResourcesSample.Azul.jpg" resource // NOTE1: Make sure not to close this stream, // or the Bitmap object will lose access to it // NOTE2: Also be very careful to match the case // on the resource name itself Stream stream = asm.GetManifestResourceStream("ResourcesSample.Azul.jpg"); // Load the bitmap from the stream this.BackgroundImage =new Bitmap(stream);</div>
(4) Mainfest Resource Namespaces
如果传递给 GetMainfestResourcesStream 方法 一个System.Type 对象,则它会用此类型的命名空间当作嵌入资源的前缀的一部分,如:
// Load the stream for resource "ResourcesSample.Azul.jpg" Stream stream = asm.GetManifestResourceStream(this.GetType(), "Azul.jpg");</div>
Bitmap 类也可以直接装载嵌入的资源,如:
// Load image from "ResourcesApp.Azul.jpg" this.BackgroundImage =new Bitmap(this.GetType(), "Azul.jpg");</div>
2. Strongly Typed Resources
在清单资源中不包含类型信息,虽然文件带有扩展名,但是类似Bitmap类是根据数据本身来判断类型的。
(1) Application Resources(.resx) Files
资源文件(.resx)的主要作用就是记录资源的相应类型信息,由于采用了.NET特定的XML方案(ResX)来保存资源类型信息。一个空的 .resx 文件也有42行内容,大多数都是方案信息。这个方案允许有许多条目信息,每个都包含name、value, comment, type 和 Multipurpose Internet Mail Extensions(MIME) type。虽然此文件是基于文本的,但是如果要编辑或者阅读,最好还是通过VS2005的资源编辑器来完成。
.resx 格式中的名称/值对在 XML 代码中打包,它描述字符串或对象值。当字符串被添加到 .resx 文件中时,该字符串的名称被嵌入在 <data> 标记中,并且值包括在 <value> 标记内,如以下示例所示。
当一个对象被插入到 .resx 文件中时,使用相同的 <data> 和 <value> 标记来描述该项,但 <data> 标记要包括类型或 MIME 类型说明符。类型说明符保留所保存对象的数据类型。如果对象由二进制数据组成,则 MIME 类型说明符保持所存储的二进制信息的基类型 (Base64)。
(2) Managing Resources
资源编辑器支持六类资源:
a. 字符串 : 在带有字符串资源的“名称”、“值”和“注释”列的设置网格中显示字符串。
b. 图像 : 显示所有图像文件(包括 .bmp、.jpg 和 .gif 格式)。这些文件在运行时作为 Bitmap 公开。此类别也包括作为 Metafile 公开的 Windows 图元文件。
c. 图标
d. 音频 : 显示声音文件(包括 .wav、.wma 和 .mp3 文件)。这些文件作为字节数组公开。
e. 文件 : 显示不适合以上类别的任何文件。此视图中的项是作为 String 公开的文本文件,或是作为字节数组公开的二进制文件。
f. 其他 : 显示用来添加其他支持字符串序列化的类型(例如,Font、Enum、Color 和 Point)的设置网格。此网格包含以下列:“名称”、“类型”、“值”和“注释”。
添加资源:
可以通过拖放、菜单选择来添加资源,通过资源编辑器添加到.resx文件的所有资源文件都会放到项目文件夹下的Resources文件夹下,如果不存在则创建。如果将一个已经存在项目里的资源添加到.resx文件中,则这个资源不会被移动或拷贝到Resources文件夹下,因为资源编辑器是通过对文件的引用来管理资源文件,resx文件仅仅存放实际清单资源的类型信息。
删除资源:
通过资源编辑器只能从.resx中移除或者剪切资源,而不能实际删除,因为你只是对资源的元数据进行操作,而并非真正的资源文件(字符串除外,它只能被嵌入)。如果从项目中删除资源文件,但是.resx中的相应元数据还在,这样在编译时就会出现编译异常。
编辑资源: 可以通过资源编辑器直接打开相应的编辑程序;
(3) Resource Persistance
链接资源作为文件存储在项目中;在编译期间,从这些文件中取得资源数据,并将其放到应用程序的清单中。应用程序的资源文件 (.resx) 只存储指向磁盘上的文件的相对路径或链接。对于嵌入资源,资源数据直接以二进制数据的文本表示形式存储在 .resx 文件中。在任何一种情况下,资源数据都将编译到可执行文件中。
注意点:字符串资源总是嵌入的资源,无法更改;文件资源总是链接的资源,也无法更改。
如何在嵌入的资源和链接的资源之间进行选择?
-----------------------------------------------------------------
在多数情况下,应该坚持默认的链接资源。但是,在有些情况下选择嵌入的资源会更好。
嵌入的资源:
如果需要在多个项目之间共享应用程序资源 (.resx) 文件,则嵌入的资源是最佳选择。例如,如果您有一个包含公司徽标、商标信息等类似内容的通用资源文件,则应使用嵌入的资源,这样您只需复制 .resx 文件,而不用复制关联的资源数据文件。不能直接编辑嵌入的资源。如果试图编辑嵌入的资源,您将会接收到一条消息,提示您将该项转换为链接的资源以便对其进行编辑;此转换是可选的,但建议进行转换。必须导出它们并在外部程序中进行修改,然后将其导回项目中。
链接的资源:
就易用性而言,链接的资源(默认值)是最好的选择。可以在项目内部直接编辑资源,并且可以根据需要轻松添加或移除资源。
-----------------------------------------------------------------
可以通过指定资源的Persistance属性来决定。如果将属性改为嵌入后,将资源文件删除并不会有什么影响,此时如果再改回链接方式,则会在Resources目录下重新创建此资源文件。
如果在资源编辑器下对资源进行管理,则会发现资源的BuildAction,即生成操作都会