在dotnet中如何使用资源(转自MS中国社区)

原创 2004年07月07日 11:56:00
如何使用资源文件

摘要
.NET 中有一套非常完善的地方化系统被定义在 System.Resources 名字空间中。不过大多数人都被 MissingManifestResourceException 这个错误困惑着。本文就是要让大家了解什么是资源文件,它有什么用处以及如何正确的调用从而避免一些"奇怪"的错误,包括 MissingManifestResourceException 这个常见错误。

目录
本文来源以及最终目的
什么是资源文件
资源文件类型
调用资源文件的几种方法
如何准确的定义资源文件的逻辑位置
推荐工具
总结
参考信息
关于作者

本文来源以及最终目的
最近作者在新闻组中看到许多有关资源文件的问题,而大多数人都有 MissingManifestResourceException 这个非常时髦的错误。所以作者考虑了一下,决定不想再让更多的人把时间都浪费在这个问题上了。这就是这篇文章的诞生原因。而最终目的除了让这个问题在新闻组上消失之外还要让大家在 10 分钟内彻底掌握资源的调用,从而成为真正的资源高手!:)

什么是资源文件
在 .NET 中准备 World-Ready 程序时需要三步,Globalization,Localizability 和 Localization。在这第三步的 Localization 中就是使用资源文件最常见的地方。(本文不讨论 World-Ready 程序,或许以后在另一篇文章中)因为程序的逻辑界面需要与资源界面隔离,而资源界面就是我们所说的资源文件。顾名思义,一个资源文件中当然全是资源,不过,什么是资源?这里所谓的资源就是程序中可利用的数据,譬如:字符串、图片和任何二进制数据,包括任何类型的文件。注意一个资源文件可以有多种语言版本,举例,一个 Strings.resources 文件可以有英语版、简体中文版、繁体中文版等。 ResourceManager 可以自动根据文件名来确认调用哪个版本。不同的版本只要在文件名中添入区域语言就可以了。比如,我们的 Strings.resources 是默认版,英语版的可以是 Strings.en-US.resources(美国英文),简体中文的可以是 Strings.zh-CHS.resources(简体中文),而繁体中文的就可以是 Strings.zh-CHT.resources(繁体中文)。所谓的默认版就是当找不到适当的资源版本时用的资源,一般都是英文。默认文件应当被嵌入到主 Assembly 中,这样就不会发生找不到资源的错误。在 VS.NET 中将一个文件的属性设为 Embedded Resource 可以使资源被嵌入到主 Assembly 中。

资源文件类型
System.Resources 名字空间支持三种资源文件:
.txt 文件,只能有字符串资源。因为不能被嵌入到 Assembly 中,所以很容易暴露,被客户修改。最大缺点是仅支持字符串资源,所以不推荐使用。
.resx 文件,由 XML 组成,可以加入任何资源,包括二进制。同样不能被嵌入到 Assembly 中。在 System.Resources 名字空间中有专用读写的类。VS.NET 创建这种文件然后将其转成 .resources 文件并根据设置将其嵌入到 Assembly 中。
.resources 文件,PE 格式,可以加入任何资源。唯一可以被嵌入到 Assembly 的文件,在 System.Resources 名字空间中有专用读写的类。

调用资源文件的几种方法
ResourceManager 可以根据不同的 UICulture 设置返回不同的本地资源(这与 World-Ready 程序有关,在此不讨论),我们只需知道调用资源用到它就可以了。接下来让我们看看如何调用每一种:
.txt 文件:
不可以直接调用,得先将其转换成 .resources 文件才能使用。(关于如何转换请看"推荐工具")
.resx 文件:
可以用 ResXResourceReader 来做读取,但是这种方法不直观,不推荐直接调用 .resx 文件。正确的方法是将其转换成 .resources 文件,然后用 ResourceManager 作读取工作。注意如果是在 VS.NET 中添加的 .resx 文件,那么它们自动被设为 Embedded Resource,转成 .resources 文件后被嵌入到 Assembly 中。
.resources 文件:
分成两种情况:
被嵌入或编译成 Satellite Assembly:
用 ResourceManager 的各种 constructor 来获得在 Assembly 中的资源。
单独文件,没被编译或嵌入到 Assembly 中:
可以用 ResourceManager.CreateFileBasedResourceManager 来获得资源集(ResourceSet),就是所有的资源。
特殊情况:
还有一种特殊情况,那就是当你直接嵌入一资源时,也就是说,不通过一个资源文件而直接将一资源嵌入到 Assembly 中。这可以在 VS.NET 中通过设置一文件的 Build 属性为 Embedded Resource 实现。在这种情况下 ResourceManager 就没有用了,因为它只能获取 .resources 资源文件(在或不在 Assembly 中)。那么如何调用这类的资源呢?不难,我们需要利用一些 Reflection 中的特征。别怕,不是让你再学 Reflection,其实我们只要了解一些 System.Reflection.Assembly 这个类中的一些函数就可以了。有三个相关函数,不过我们只需要 Assembly.GetManifestResourceStream 这个函数。这个函数将一嵌入到 Assembly 中的资源以 stream 的方式返回,而我们可以将这个 stream 转成在 .NET 中可用的对象。比如,如果嵌入资源是一图片,那么我们可以利用 New Bitmap(Stream) 这个 Bitmap 的 constructor 获得这个图片资源的 Bitmap 对象。
注:在这里仅介绍怎样获得不同的资源的方法,关于怎样用各个类与函数请参看有关文档。

如何准确的定义资源文件的逻辑位置
我想这是许多人最关注的一段了!在这里作者将解说如何正确的填写 ResouceManager(String, Assembly) 这个 constructor,还有如何正确的填写 Assembly.GetManifestResourceStream(String),因为它们两个的原理是相同的。看过了上面的描述,到了这里就简单多了。这里主要讨论的是怎么填写那个 String。这个 String 就是资源的完整名,一个完整名由它的名字空间和文件名前部分(BaseName)组成。例如,如果默认名字空间(root namespace)是 DefaultNamespace,资源文件的名字是 Strings.en-US.resources,那么它的完整名就是 DefaultNamespace.Strings。这个很简单,不过怎样确定名字空间呢?这就有些奇怪了,因为 C# 的编译器与 VB.NET 的编译器有些不同。作者在这里分别给出两个编译器怎样给嵌入资源自动添加命名空间:
C#
它自动添加 default namespace(与 root namespace 相同),但也添加子文件夹的名字。例如,在 Subfolder 子文件夹下放的资源文件 Strings.en-US.resources,它的完整名是 default namespace + subfolder + base name = DefaultNamespace.Subfolder.Strings
VB.NET
在 VB.NET 中就很简单了,它自动给嵌入资源添加 root namespace。不管你在哪个子文件夹中放置资源文件,资源文件的完整名永远是 root namespace + base name。
根据上面的描述,如果我们使用 C#,用 VS.NET 在 NewFolder 这个子文件夹中添加了一个叫 Images.resources 的资源文件,那么我们应该用以下代码获取这些资源,假设 default namespace 是 MyDefault:
ResourceManager res = new ResourceManager("MyDefault.NewFolder.Images", this.GetType().Assembly);
但如果我们用 VB.NET 的话,就应该这样:
Dim res As New ResourceManager("MyDefault.Images", Me.GetType().Assembly)

推荐工具
resgen.exe:SDK 中的工具,专门用来做资源文件类型之间的转换。支持 .txt <-> .resx <-> .resources 之间的转换。
Resourcer:专门用来创建资源文件,简单易用,支持 .resx 与 .resources 文件格式。(http://www.aisto.com/roeder/dotnet)
.NET Reflector:用来浏览 Assembly。如果你不确定一个资源文件的完整名时可以用这个工具在 Assembly 中查看。(http://www.aisto.com/roeder/dotnet)

总结
本文中谈及了以下内容:
什么是资源
什么是资源文件
.NET 中有哪几类资源文件
如何定义资源文件的逻辑位置
调用资源文件的几种方法
本文通过正确定位资源文件而解决了那个非常时髦的 MissingManifestResourceException。本文给了您一个很丰富资源调用经验。想让您完全了解有关资源文件的任何可能问题,当然也会有漏洞。如果有的话希望大家谅解!

参考信息
以下是一些文档的链接,如果您的帮助是中文的话请在 MSDNVS 后添加".2052":
Resource File Generator (Resgen.exe)
ms-help://MS.VSCC/MS.MSDNVS/cptools/html/cpgrfresourcefilegeneratorutilityresgenexe.htm
Resources in Applications
ms-help://MS.VSCC/MS.MSDNVS/cpguide/html/cpconcreatingusingresources.htm
Resource Fallback Process
ms-help://MS.VSCC/MS.MSDNVS/cpguide/html/cpconpackagingdeployingresources.htm #cpconpackagingdeployingresourcesanchor1

关于作者
作者:袁伟(Kefroth)
电子邮件:kefroth@interlap.com.ar

Struts2的国际化和访问资源文件的几种方式

资源文件的命名:basename_language_country.properties JAVA国际化 如果系统同时存在资源文件、类文件,系统将以类文件为主,而不会调用资源文件。 对于简体...
  • lotusyangjun
  • lotusyangjun
  • 2016年06月02日 14:50
  • 2938

页面 和 Action 中如何获取 国际化资源文件的 value值 ?

如何在页面上 和 Action 类中访问国际化资源文件的  value 值 1 . 在 Action 类中. 若 Action 实现了 TextProvider 接口, 则可以调用其 getT...
  • chuck_kui
  • chuck_kui
  • 2016年05月11日 20:05
  • 1199

使用native2ascii命令处理Struts2国际化资源文件

native2ascii是sun java sdk提供的一个工具。用来将别的文本类文件(比如*.txt,*.ini,*.properties,*.java等等)编码转为Unicode编码。为什么要进行...
  • w13151556135
  • w13151556135
  • 2014年04月30日 12:16
  • 1183

ext js组件省市联动--转自开源中国社区

代码片段(1)[全屏查看所有代码] 1. [文件] EXTJS组件省市联动_修改.js.js ~ 7KB     下载(131)      ? 1 2 ...
  • u012046748
  • u012046748
  • 2014年09月30日 10:02
  • 258

给年轻程序员的几句话--转自开源中国社区

本文是我在CSDN的第一个微博!我决定以后每天都发表微博,不管是不是原创,风雨无阻!--chinacyr 本文是从 Letter to a Young Developer 这篇文章翻译而来。...
  • chinacyr
  • chinacyr
  • 2011年11月27日 00:27
  • 1007

linux线程实现机制分析----------转自IBM中国开发者社区

一.基础知识:线程和进程 按照教科书上的定义,进程是资源管理的最小单位,线程是程序执行的最小单位。在操作系统设计上,从进程演化出线程,最主要的目的就是更好的支持SMP以及减小(进程/线程)上下文...
  • hao707822882
  • hao707822882
  • 2014年09月11日 08:10
  • 452

如何编辑SDE数据(转自ESRI中国社区)

很多刚入门的朋友对SDE数据并不太了解,接二连三的在社区里面发问,有时也得不到很好的解答,对此懒羊羊也深感同情。想到刚入门时的痛苦,懒羊羊决定抽写时间出来详细的讲述如何去编辑SDE数据,希望可以跟广大...
  • qinyilang
  • qinyilang
  • 2011年05月31日 07:32
  • 2380

全图范围设置(转自Esri中国社区)

全图范围设置 Arcmap的FullExtent默认是地图加载的时候的extent。其实这个fullExtent是可以设置的。 在左边图例的dataFrame 点击右键,属性,如下...
  • hongtashan11
  • hongtashan11
  • 2011年10月27日 12:00
  • 1345

ACM算法书籍推荐(转自开源中国社区-heartfly)

我常感叹到,学计算机的人是幸福的,因为在这个领域中有如此多的通俗易懂(相对来说)的经典好书,你需要做的只是坚持把它们一本一本读下去而已。学力学就没有这样的好事了(抱怨一下),除了论文就是论文,满篇公式...
  • tyuttjx
  • tyuttjx
  • 2012年08月14日 23:02
  • 1394

开发中国社区使用

开发中国社区使用介绍开源中国社区 官方网站 https://git.oschina.net/ • 开源中国社区成立于2008年8月,其目的是为中国的IT技术人员提供一个全面的、快捷更...
  • kdlylx
  • kdlylx
  • 2016年07月08日 13:21
  • 176
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:在dotnet中如何使用资源(转自MS中国社区)
举报原因:
原因补充:

(最多只允许输入30个字)