c# 工程里面,经常会添加资源文件。

作用:

  1. 一处文本多个地方的UI使用,最好把文本抽成资源,多处调用使用一处资源。
  2. 多语言版本支持,一份代码支持多国语言。配置多国语言的资源文件,调用处引用资源。

例如,新建一个简单的 .net framework console 工程,添加一个资源并使用。

现在可以使用资源了:

        static void Main(string[] args)
{
var tooltip = Resource1.ToolTip;
}

  

好奇心驱使着我看看VS怎么使用这个resx类型的文件的,于是查了一下文档,下面做个总结。

一 最简单的资源:文本资源

生成这样的资源成本极低,一个txt文本就可以。按照 key=value这样的格式一行一行的写好就好啦~

新建一个txt,写两个资源,name 和 age

使用工具 resgen.exe 生成资源文件。

resgen my-resource.txt

 

查看产物:

 

查看二进制文件到底长啥样,可以看到里面写了我们存的两个资源。至于其他文本估计是微软自己搞得格式~

看到了吗,最下面几个二进制数字对应的字符就是 age name 12 zhangsan 这些资源文件的信息。

现在我们编写代码去使用我们的资源(最朴素的txt文件写点c# code, 这样直观明了)

代码如下:

namespace MyTestResourceNamespace
{
class Program
{
static void Main(string[] args)
{
var rm = new System.Resources.ResourceManager("my-resource",
System.Reflection.Assembly.GetExecutingAssembly());
var name = rm.GetString("name");
System.Console.WriteLine(name);
}
}
}

  

使用csc工具,就能直接做成exe

csc test-resource.cs

  

产物:

现在直接调用exe自然会抛出异常,因为我们还没有嵌入我们的资源文件。

使用reflector查看:

这里有两种方法,一个是生成exe的时候就嵌入。还有一种是生成好的exe用AL.exe这个工具嵌入资源。

先使用方法1:

csc test-resource.cs -resource:my-resource.resources

 

这次再查看reflector瞅瞅,这次资源成功嵌入到exe啦

对比两次的exe二进制数据的不同,很容易发现,资源文件被嵌入到exe的某一段了。至于位置微软自己肯定知道,不需要我们操心

这次再次调用这个exe:

test-resource.exe

  

命令行输出:

zhangsan

  

二 最常用的资源:Resx类型资源

新建一个文件,命名为 test-resource.resx 这次写入两个资源,Name Age

<?xml version="1.0" encoding="utf-8"?>
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Age" xml:space="preserve">
<value>20</value>
</data>
<data name="Name" xml:space="preserve">
<value>Cherry</value>
</data>
</root>

  

重点在于:

同样使用工具 resgen生成资源文件:

 
为了对比,新建一个txt,写入一样的资源
也生成资源文件:
 
用二进制查看器对比两个资源文件的区别,发现没有区别。
 
那为什么要用resx格式管理资源?
原因是resx类型资源可以放置各种类型,不单单是字符串,还可以是图片,音频,视频等等。
 
常见用例:
新建一个winform工程,给Form添加一个背景图片:
 
这时候观察我们的工程目录下,VS已经生成好了 Form1.resx文件,并且添加了一个图片资源
 
打开这个文件,可以看到里面放了一个资源:
 
三 Visual Studio 如何管理工程资源
 
正如前面举的例子,在 Visual Studio 里新建的工程可以使用它的GUI轻松的添加资源。
如果我们自己写resx文件,很难维护。字符串还好说,向上面的图片存储的是base64字符串,就很难维护。
 
回顾之前的console工程,他是怎么用资源的?
var tooltip = Resource1.ToolTip;

仔细观察VS帮我们多生成了一个cs文件:

仔细看cs 文件的内容:

重点在于这两处:

     /// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ConsoleApp10.Resource1", typeof(Resource1).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
        /// <summary>
/// Looks up a localized string similar to This is a tool tip.
/// </summary>
internal static string ToolTip {
get {
return ResourceManager.GetString("ToolTip", resourceCulture);
}
}

看来VS生成的代码与我们之前的写法一致

那么图片资源呢?

我们对于图片其实也可以用原来的方法:

        // 1. 方法一
this.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("$this.BackgroundImage")));         // 2. 方法二
var bitmap = new System.Resources.ResourceManager("WindowsFormsApp8.Form1",
Assembly.GetExecutingAssembly()).GetObject("$this.BackgroundImage");
            this.BackgroundImage = (System.Drawing.Bitmap)bitmap;

四 Visual Studio 如何生成资源

下面分析一下,Visual Studio 如何生成资源,依旧是一个最简单的 console 工程,如下图,注意添加了一个resource文件

编译,并输出详细的log信息:

重点观察这两步:

比较我们最早期生成资源的方法:

resgen.exe Resource1.resx

 

其实本质是一样的,只是VS多使用了一些参数。

查了下文档,使用Resgen的方法:

resgen [-define:symbol1[,symbol2,...]] [/useSourcePath] filename.extension | /compile filename.extension... [outputFilename.extension] [/r:assembly] [/str:lang[,namespace[,class[,file]]] [/publicclass]]

再来看看VS使用的那几个之前不了解的参数:

第一个参数 useSourcePath 用来确认相对路径参照哪个路径,/r 用来引用资源文件里的不同Type,compile指定输入的资源文件和输出的名称。

现在VS编译资源文件的思路已经非常清晰了。

在观察下VS嵌入资源的方法:

同样是用csc,比较我写的命令是:

csc test-resource.cs -resource:my-resource.resources

但是VS 使用的参数就很多了,我挑了几个重要的参数介绍一下:

1. /reference

代码里面引用了别的dll的东西,需要通过reference来标明在哪找到这些dll,进而在编译时不会出错。

如果引用了a.dll,并且a.dll引用b.dll,在a中如果使用了b的类型,那么b也需要列举出来。

如果引用了两个dll,中间有相同的namspace class,需要起个别名作为区分:

-reference:a=a.dll
-reference:b=b.dll

在引用他们的代码里要说清楚到底用哪个dll里面的class

extern alias a;
extern alias b; var stu1 = new a::Student();
var stu2 = new b::Student();

2. /out

最终产出的文件名

3. /target

目标产物的类型,常用的就三种:

exe   做成控制台程序

winexe  做成桌面应用程序

library  做成dll

4. /resource

嵌入资源,我们要验证的关键点。看来VS也使用了这个参数来注入资源文件

再接下来你可以看到列举出来要编译哪些cs文件,重点

Program.cs
Properties\AssemblyInfo.cs Resource1.Designer.cs

就这俩文件了

再剩下的一些参数大致也能猜到意思了。

总结一下:VS其实和我们之前做的实验完全一致,但是强大的IDE帮助我们做了这些枯燥繁琐的事情,使得我们可以把注意力到放到代码的开发上面。

关于c#里面资源的一个简单的介绍先就到这里技术啦~

从VisualStudio资源文件看.NET资源处理的更多相关文章

  1. FineUIPro中如何支持多语言(全局资源文件和本地资源文件)

    一个客户在邮件中问到了FineUIPro的多语言实现问题,其实 FineUIPro 并没有对此做特殊处理,因此直接使用 ASP.NET 原生支持的资源文件就能实现. 下面我们就以FineUIPro的空 ...

  2. Windows Store App 全球化:引用分离资源文件中的资源

    大部分应用程序仅需要单个默认资源文件,例如Strings/zh-CN/Resources.resw,但是在某些应用程序中,最好将资源分离到多个资源文件中,以便更好地组织资源内容,这样就需要考虑如何引用 ...

  3. C#调用Resources.resx资源文件中的资源

    使用到了.NET中的资源文件,也就是Resources.resx,于是就学会了如何调用资源文件中的资源.首先,资源文件可以从项目属性中的资源标签添加.比如,我添加一个图片,叫做aaa.png,添加入资 ...

  4. C#资源文件与与资源名称字符串之间的互相转化

    1.使用ResourceManager string st = Properties.Resources.ResourceManager.GetString(tableName);value = Pr ...

  5. Maven学习-处理资源文件

    在前面两篇文章中,我们学习了Maven的基本使用方式和Maven项目的标准目录结构.接下来,我们来看下Maven是如果管理项目中的资源文件的. Java项目的资源文件,主要用于存储系统的配置信息,以及 ...

  6. (转)Maven学习-处理资源文件

    转自:http://www.cnblogs.com/now-fighting/p/4888343.html 在前面两篇文章中,我们学习了Maven的基本使用方式和Maven项目的标准目录结构.接下来, ...

  7. 【java】获取解析资源文件的方法

    关于资源文件的读取,有很多种方法,下面补充了多种方法 1.java.util.ResourceBundle 使用java自带的util包下的ResourceBundle类获取,使用方法最简单 //获取 ...

  8. delphi资源文件的使用

    delphi资源文件的使用 资源文件(*.res)通过编译指令 $R 关联, 譬如工程文件 Project1 中的 {$R *.res} 就是关联 Project1.res 资源文件, 我们直接写作 ...

  9. WPF国际化方式1之资源文件

    先看效果吧,个人觉得由于MVVM模式的UI响应属性变化的特殊机制,资源文件和内存数据都是国际化不错的选择. 1.首先准备两个资源文件用来做中文和英文的转换使用,将程序中需要转换语言都弄成两个版本,分别 ...

随机推荐

  1. Java日期时间API系列1-----Jdk7及以前的日期时间类

    先看一个简单的图: 主要的类有: Date类负责时间的表示,在计算机中,时间的表示是一个较大的概念,现有的系统基本都是利用从1970.1.1 00:00:00 到当前时间的毫秒数进行计时,这个时间称为 ...

  2. [20190823]关于CPU成本计算3.txt

    [20190823]关于CPU成本计算3.txt --//前几天探究CPU cost时遇到的问题,获取行成本时我的测试查询结果出现跳跃,不知道为什么,感觉有点奇怪,分析看看.--//ITPUB原始链接 ...

  3. [20190524]使用use_concat or_expand提示优化.txt

    [20190524]使用use_concat or_expand提示优化.txt --//上午看了链接https://connor-mcdonald.com/2019/05/22/being-gene ...

  4. Web服务器—IIS

    https://blog.csdn.net/qq_33323054/article/details/81628627 https://jingyan.baidu.com/article/67508eb ...

  5. 【bzoj1941】[Sdoi2010]Hide and Seek(kd-tree)

    bzoj 题意: 给出\(n\)个点,对于每个点,\(d_i\)等于距离其最远的点的距离减去距离最近的点的距离.这里的距离为曼哈顿距离. 求\(min\{d_i\}\). 思路: 考虑直接对每个点暴力 ...

  6. C#所有经典排序算法汇总

    1.选择排序 选择排序 class SelectionSorter     {         private int min;         public void Sort(int[] arr) ...

  7. Python常用数据类型简介

    1.变量的三个基本特征 1,大印 2,判断变量值是否相等 3,判断变量id是否相等 2.常用数据类型分类 数字类型(int) 字符串类型(str) 列表类型(list) 字典类型(dict(dicti ...

  8. [C11] 推荐系统(Recommender Systems)

    推荐系统(Recommender Systems) 问题阐述(Problem Formulation) 将 推荐系统 纳入这门课程来讲有以下两个原因: 第一.仅仅因为它是机器学习中的一个重要的应用.在 ...

  9. 【声明式事务】Spring事务介绍(一)

    事务管理对于企业应用来说是至关重要的,当出现异常情况时,它也可以保证数据的一致性. Spring事务有两种管理方式:编程式事务和声明式事务 编程式事务使用TransactionTemplate或者直接 ...

  10. Keras:

    https://keras.io/zh/layers/core/ keras使用稀疏输入进行训练 2018.06.14 12:55:46字数 902阅读 760 稀疏矩阵 稀疏矩阵是指矩阵中数值为0的 ...