热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

C#Resources资源详解

这篇文章主要为大家详细介绍了C#Resources资源,包括ResourceBasics、StronglyTypedResources等,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

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);
}

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);

(4) Mainfest Resource Namespaces

如果传递给 GetMainfestResourcesStream 方法 一个System.Type 对象,则它会用此类型的命名空间当作嵌入资源的前缀的一部分,如:

// Load the stream for resource "ResourcesSample.Azul.jpg"
Stream stream = asm.GetManifestResourceStream(this.GetType(), "Azul.jpg");

Bitmap 类也可以直接装载嵌入的资源,如:

// Load image from "ResourcesApp.Azul.jpg"
this.BackgroundImage =new Bitmap(this.GetType(), "Azul.jpg");

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 文件中时,该字符串的名称被嵌入在 标记中,并且值包括在 标记内,如以下示例所示。
当一个对象被插入到 .resx 文件中时,使用相同的 标记来描述该项,但 标记要包括类型或 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,即生成操作都会变为“无”。其实Persistance属性仅仅在设计期间起作用,最终资源数据都将编译到可执行文件中。

(4) Using Typed Resources

* 直接使用.resx文件

利用 ResXResourceReader 类来访问.resx 文件;
此类可以枚举 XML 资源 (.resx) 文件和流,并读取顺序资源名称和值对,存在于命名空间 System.Resources。如果要提取特定条目,则需要先进行遍历寻找。

using( ResXResourceReader reader =
 new ResXResourceReader(@"C:\MyResources.resx") ) {
 foreach( DictionaryEntry entry in reader ) {
  string s =string.Format("{0} ({1})= '{2}'",
    entry.Key, entry.Value.GetType(), entry.Value);
   MessageBox.Show(s);
  }
}

* 使用编译的.resx 资源

您可以采用三种不同的方式创建资源文件。如果您的资源将只包含字符串数据,则最简单的方法是手动创建文本文件。如果您的资源将包含对象或字符串与对象的组合,则您必须创建 .resx 文件或 .resources 文件。只有.resources 文件才应嵌入在公共语言运行库程序集和附属程序集中。资源文件生成器 (Resgen.exe) 将文本 (.txt) 文件和基于 XML 的资源 (.resx) 文件转换成 .resources 文件,

资源生成器 Resgen.exe :
将 .txt 文件转换为 .resources 文件,方法是包装由 ResourceWriter 类实现的方法。Resgen.exe 还包装 ResourceReader,这使您可以使用该工具来将 .resources 文件转换回 .txt 文件。

编译项目后会将.resx数据嵌入为嵌套资源放在资源清单,例如项目缺省命名空间为A,rest文件为B.resx,则这个嵌套资源容器则为 A.B.resources,可以在ildasm中查看。对它的读取利用 ResourceReader 类,也不支持随机访问。

using( ResourceReader reader =
 new ResourceReader("MyResources.resources") ) {
 foreach( DictionaryEntry entry in reader ) {
  string s =string.Format("{0} ({1})= '{2}'",
    entry.Key, entry.Value.GetType(), entry.Value);
   MessageBox.Show(s);
  }
}

其实还可以直接通过对清单资源流的访问来操作 .resources 文件。

Assembly asm = Assembly.GetExecutingAssembly();

// Load embedded .resources file
using(
  Stream stream = asm.GetManifestResourceStream(
  this.GetType(),
  "MyResources.resources") ) {

 // Find resource in .resources stream
 using( ResourceReader reader =new ResourceReader(stream) ) {
  foreach( DictionaryEntry entry in reader ) {
   if( entry.Key.ToString() =="MyString" ) {
    // Display string resource value
     MessageBox.Show("MyString = "+ (string)entry.Value);
    break;
    }
   }
  }
}

以上都需要进行多步操作而且不支持随机访问,但是.NET提供了 ResourceManager 类来支持对资源的随机访问。

(5) Resource Manager

ResourceManager 类可以查找区域性特定的资源,当本地化资源不存在时提供代用资源,并支持资源序列化,它其实也就是对ResourceReader的封装。它由一个嵌入.resource文件初始化:

Assembly asm =this.GetType().Assembly;
ResourceManager resman =new ResourceManager("ResourcesSample.MyResources", asm);

通过 ResourceManager 的方法,调用方可使用 GetObject 和 GetString 两种方法访问特定区域性的资源。

// Load ResourcesSample.MainForm.resources from MainForm.resx
ResourceManager resman =new ResourceManager(this.GetType());

// Access the MyString string resource from the ResourceManager
// (these two techniques are equivalent for strings)
string s1 = (string)resman.GetObject("MyString");
string s2 = resman.GetString("MyString");

(6) 强类型资源类

Resource Manager 提供了对资源的弱类型方法GetObject来返回资源,需要进行类型转换。但是VS2005和一个自定义工具 ResXFileCodeGenerator 提供了对这个问题的解决办法。当一个 .resx 文件被保存时,VS2005会应用自定义工具将其产生一个相应的 .Designer.cs 文件,此文件提供了一个名字和 .resx 文件相同的类,这个类所处的命名空间为 defaultNamespace.projectPath。

namespace ResourcesSample {
  ///
  ///    A strongly typed resource class, for looking up localized
  ///    strings, etc.
  ///
  // This class was autogenerated by the StronglyTypedResourceBuilder
  // class via a tool like ResGen or Visual Studio.
  // To add or remove a member, edit your .resx file and then rerun ResGen
  // with the /str option, or rebuild your VS project.
  internalclass MyResources {
   static global::System.Resources.ResourceManager resourceMan;
   static global::System.Globalization.CultureInfo resourceCulture;

   internal MyResources() {}

   ///
   ///  Returns the cached ResourceManager instance used by this
   ///  class.
   ///
   internalstatic global::
    System.Resources.ResourceManager ResourceManager {
    get {
     if( (resourceMan ==null) ) {
      global::System.Resources.ResourceManager temp =
       new global::System.Resources.ResourceManager(
        "ResourcesSample.MyResources",
        typeof(MyResources).Assembly);
      resourceMan = temp;
     }
     return resourceMan;
    }
   }

   ///
   ///  Overrides the current thread's CurrentUICulture property for
   ///  all resource lookups using this strongly typed resource class.
   ///
   internalstatic global::System.Globalization.CultureInfo Culture {
    get { return resourceCulture; }
    set { resourceCulture = value; }
   }
  }
}

由以上可以看出 MyResource 类型的两个特征:

a. 它通过一个ResourceManager类型的属性提供了对ResourceManager的静态访问,就没必要写之前的创建逻辑了; b. 通过一个Culture属性提供了CultureInfo对象实现对本地化信息的静态访问;

提供的每个资源都是强类型静态只读属性。在内部实现中,每个属性都由设计器生成的资源类利用托管的ResourceMananger对象产生的;

// Access strongly typed resources from MyResources.resx
string myString = MyResources.MyString;
Icon myIcon = MyResources.MyIcon;

(7) Designer Resources

VS2005提供了整个项目的资源管理。由于Resources.resx 文件是从项目的属性页来进行管理的,所以 VS2005将它存放到项目的Properties文件夹中。当在项目中添加.resx文件时,ResXFileCodeGenerator工具会自动生成Resources.Designer.cs:

namespace ResourcesSample.Properties {
   ...
   internal class Resources {
   ...

则可以如下来访问资源:MessageBox.Show(Properties.Resources.MyString);

项目会自动生成一个跟窗体关联的.resx 文件,保存类似 BackgroundImage 和 Icon 等资源信息。属性窗口可以打开选择资源编辑器,允许选择适当的图片资源。它提供了两种导入和保存资源的方式:作为本地资源;作为项目资源文件。对于窗体,本地资源被嵌入到窗体设计器自动创建的.resx文件中并和窗体关联,如果选择本地资源,则可以直接将图片导入到窗体的资源文件中。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


推荐阅读
  • PDF内容编辑的两种小方法,你知道怎么操作吗?
    本文介绍了两种PDF内容编辑的方法:迅捷PDF编辑器和Adobe Acrobat DC。使用迅捷PDF编辑器,用户可以通过选择需要更改的文字内容并设置字体形式、大小和颜色来编辑PDF文件。而使用Adobe Acrobat DC,则可以通过在软件中点击编辑来编辑PDF文件。PDF文件的编辑可以帮助办公人员进行文件内容的修改和定制。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • 本文讨论了Alink回归预测的不完善问题,指出目前主要针对Python做案例,对其他语言支持不足。同时介绍了pom.xml文件的基本结构和使用方法,以及Maven的相关知识。最后,对Alink回归预测的未来发展提出了期待。 ... [详细]
  • Win10下游戏不能全屏的解决方法及兼容游戏列表
    本文介绍了Win10下游戏不能全屏的解决方法,包括修改注册表默认值和查看兼容游戏列表。同时提供了部分已经支持Win10的热门游戏列表,帮助玩家解决游戏不能全屏的问题。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文介绍了在SpringBoot中集成thymeleaf前端模版的配置步骤,包括在application.properties配置文件中添加thymeleaf的配置信息,引入thymeleaf的jar包,以及创建PageController并添加index方法。 ... [详细]
  • Java验证码——kaptcha的使用配置及样式
    本文介绍了如何使用kaptcha库来实现Java验证码的配置和样式设置,包括pom.xml的依赖配置和web.xml中servlet的配置。 ... [详细]
  • 如何在服务器主机上实现文件共享的方法和工具
    本文介绍了在服务器主机上实现文件共享的方法和工具,包括Linux主机和Windows主机的文件传输方式,Web运维和FTP/SFTP客户端运维两种方式,以及使用WinSCP工具将文件上传至Linux云服务器的操作方法。此外,还介绍了在迁移过程中需要安装迁移Agent并输入目的端服务器所在华为云的AK/SK,以及主机迁移服务会收集的源端服务器信息。 ... [详细]
  • 在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板
    本文介绍了在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板的方法和步骤,包括将ResourceDictionary添加到页面中以及在ResourceDictionary中实现模板的构建。通过本文的阅读,读者可以了解到在Xamarin XAML语言中构建控件模板的具体操作步骤和语法形式。 ... [详细]
  • 本文介绍了使用cacti监控mssql 2005运行资源情况的操作步骤,包括安装必要的工具和驱动,测试mssql的连接,配置监控脚本等。通过php连接mssql来获取SQL 2005性能计算器的值,实现对mssql的监控。详细的操作步骤和代码请参考附件。 ... [详细]
  • Spring常用注解(绝对经典),全靠这份Java知识点PDF大全
    本文介绍了Spring常用注解和注入bean的注解,包括@Bean、@Autowired、@Inject等,同时提供了一个Java知识点PDF大全的资源链接。其中详细介绍了ColorFactoryBean的使用,以及@Autowired和@Inject的区别和用法。此外,还提到了@Required属性的配置和使用。 ... [详细]
  • 本文介绍了一个免费的asp.net控件,该控件具备数据显示、录入、更新、删除等功能。它比datagrid更易用、更实用,同时具备多种功能,例如属性设置、数据排序、字段类型格式化显示、密码字段支持、图像字段上传和生成缩略图等。此外,它还提供了数据验证、日期选择器、数字选择器等功能,以及防止注入攻击、非本页提交和自动分页技术等安全性和性能优化功能。最后,该控件还支持字段值合计和数据导出功能。总之,该控件功能强大且免费,适用于asp.net开发。 ... [详细]
  • 如何实现JDK版本的切换功能,解决开发环境冲突问题
    本文介绍了在开发过程中遇到JDK版本冲突的情况,以及如何通过修改环境变量实现JDK版本的切换功能,解决开发环境冲突的问题。通过合理的切换环境,可以更好地进行项目开发。同时,提醒读者注意不仅限于1.7和1.8版本的转换,还要适应不同项目和个人开发习惯的需求。 ... [详细]
  • 如何更改电脑系统的自动校时服务器地址?
    本文介绍了如何通过注册表编辑器更改电脑系统的自动校时服务器地址。通过修改注册表中的数值数据或新建字符串数值的方式,可以将默认的时钟同步服务器地址更改为自己所需要的域名或IP地址。详细步骤包括双击时间区域,点击internet时间,勾选自动校正域名设置定时等操作。 ... [详细]
  • 使用chrome编辑器实现网页截图功能的方法
    本文介绍了在chrome浏览器中使用编辑器实现网页截图功能的方法。通过在地址栏中输入特定命令,打开控制台并调用命令面板,用户可以方便地进行网页截图操作。 ... [详细]
author-avatar
郝蕾雅老_206
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有