为.Net程序集添加资源
作者:宋华 本文选自:赛迪网 2002年12月06日
在.Net结构中,程序集Assembly(也称着程序集或托管Dll)是自我描述的安装单元,它可以只包括一个PE(可移植可执行)格式的Dll或exe文件,也可以由多个文件组成,例如资源(位图、JPEG文件、字符串表等)、Dll和exe等。
其中,资源是一个范围广泛的概念,可以由多种元素组成,包括与用户交互的界面元素(如位图、图标或光标)、应用程序所需数据的自定义文件以及安装 API 使用的版本文件、菜单和对话框等都可以作为资源。
资源是可以重用的,在必要的时候也能对资源进行编辑修改,当我们这样做时,最好能将这些资源文件独立出来,以类似.Net模块的方式来构建程序集资源,使资源文件独立于源代码。这样,不但可以在不同的程序集中自由引用这些资源,还可以使非专业编程人员很容易地修改资源(当然,通过程序员,或者简单的批处理文件就可以把他们重新编译为新的资源文件),这种独立地对资源文件进行的修改不会引发对引用它的程序集的影响。同时,使用资源文件还有助于把应用程序本地化为不同的语言。辅助程序集正是因为只包含资源而不包含程序代码才广泛用于应用程序的本地化编程。
.Net结构对资源文件提供了大量支持。使用Visual Studio.Net集成开发环境IDE很容易创建资源文件,把资源添加到工程中的方法和添加窗体、类库一样简单,唯一不同的是你需要设置资源的“BuildAction”属性为“Embedded Resource”,此后,就可以使用这些资源。
从上面可以知道,字符串表是极常见的一种资源。要创建这类资源文件,有以下两种方式:
1)、使用.Net命令行工具ResGen创建。首先创建包含资源内容的文本文件,这可以使用一般的文本编辑软件如记事本、EditPlus等。该文本文件由所需要的“键值对”组成,键的名称可以在程序中引用,设置键名后把字符串值赋予该键即可完成文件的创建。作为示例,以下语句段产生这样的资源,按下面的格式保存为userinfo.txt文件:
Username="Songh"; Sex="Boy"; Birthday="1973-01-15"; Salary="5000RMB"; |
然后,把文本文件转换为资源文件,这仍然通过ResGen工具来实现。执行以下语句:ResGen userinfo.txt,就将生成资源文件userinfo.resources。另外,ResGen还可以创建基于XML格式的.resX资源文件,执行以下命令ResGen userinfo.resources userinfo.resx 就将生成Xml格式的资源userinfo.resx。不过,ResGen工具不支持图象资源的操作,下面的方法就不具有这样的限制。
2)、使用ResourceWriter类
为易于创建资源文件,.Net结构提供了ResourceWriter类以支持图象等各种资源类型的创建。ResourceWriter类包含的方法能以系统默认的格式将资源写入输出文件或输出流。与方法1)不同的是,这里统一在一个过程中完成。
要创建一个资源文件,请调用ResourceWriter类的构造函数初始化类实例并至少提供流名或文件名。资源的实际内容通过调用AddResource方法来完成,AddResource方法将资源指定为名称和值对。资源的实际写入需要调用Generate方法来实现,不过,在调用Close方法关闭该ResourceWriter时将隐式调用Generate方法。
ResourceWriter.AddResource()方法向要写入资源的列表中添加资源。在创建ResourceWriter类实例后,该方法可以添加至多2GB的资源,下面的重载方法之一用于向资源列表中添加string资源:
public void AddResource( string name,//键名 string value//值 ); |
在这里,AddResource方法的第一个参数指定键名称,第二个参数指定值。多次调用该方法就可以完成字符串表的创建。另外,添加图象资源可以通过实例化类Image来实现(这时,请添加System.Drawing名称空间)。
下面的代码段生成包含字符串表和图象的资源文件userinfo.resources。
using System; using System.Resources; using System.Drawing; public class RS { public static void Main() { ResourceWriter rw=new ResourceWriter("userinfo.resources");//提供文件名以初始化ResourceWriter类实例。 Image image=Image.FromFile("photo.gif");//实例化Image类 rw.AddResource("Photo",image);//添加图象 rw.AddResource("Username","songh");//添加字符串 rw.AddResource("Sex","boy");//添加字符串 rw.AddResource("Birthday","1973-01-15");//添加字符串 rw.AddResource("Salary","5000RMB");//添加字符串 rw.Close();//关闭ResourceWriter并隐式调用Generate()方法完成资源文件写入磁盘文件。 } } |
上面的代码首先打开图形文件photo.gif,创建一个Image对象。这样做时,这个图形文件必须存在于工程可执行文件的目录(通常是项目的/Bin/Debug目录)下,或者在Image.FromFile()的方法参数中指定图象的完整路径。然后,通过几次调用AddResouce()方法把字符串资源添加到ResourceWriter对象中。最后,调用Close()方法关闭ResourceWriter对象并隐式调用Generate()方法把资源写入文件userinfo.resources。
编译以上代码并运行就将创建资源文件userinfo.resources。
以上两种方式生成的资源文件均可以作为一个外部文件添加到程序集中,或者内嵌到Dll或exe中。下面继续说明如何在Windows应用程序使用资源文件。
使用资源文件
使用Visual Studio.Net集成开发环境IDE,可以把很容易把资源文件添加到程序集中。只需要在创建的工程中添加已经存在的资源文件,简单设置其属性就可将资源文件嵌入该程序集。下面通过一个C# Windows控制台实例来说明任何使用上面创建的userinfo.resources资源文件。
首先,创建C# Windows Console项目ResourceUserinfo,打开"项目/添加现有项",找到前面创建的资源文件Userinfo.resources添加到这个工程中;
然后,选择这个资源文件,将属性BuildAction(生成操作)设置为Embedded Resource(嵌入的资源),这样,资源文件就可以嵌入到输出的程序集中。
现在,你可以使用这个资源文件了。System.Resources名称空间中的ResourceManager类提供在运行时方便地访问特定资源的途径。具体地可以通过GetObject和GetString方法来实现,以键名为参数就将返回对应的值。
ResourceManager类的构造函数初始化ResourceManager类的新实例,其重载方法之一查找包含在一些文件中的资源,这些文件是使用给定的 Assembly 从指定根名称导出的。
public ResourceManager( string baseName, Assembly assembly ) |
其中,参数baseName表示资源的根名称。根名称由应用程序名称空间和资源文件名(不带扩展名)组成。这样,该例中资源的根名称应该是:UserinfoResource.Userinfo,通过调用GetManifestResourceNames()方法也可编程获取该名称。
另一个参数assembly表示的是当前的主程序集,本例中的主程序集其实也是正在执行的程序集。获取正在执行程序集的一个简单方法是调用Assembly.GetExecutingAssembly()方法。
在获取ResourceManager实例后,通过指定键名,就可以获得对应的资源。
下表是程序中使用的部分控件:
类别 | TextBox | TextBox | TextBox | TextBox | PictureBox |
名称 | username | sex | birthday | salary | photo |
这些控件均可直接从工具箱拖放到设计器中。
完整的源代码为:
using System.reflection; using System.Resources; private System.Resources.ResourceManager rm; public Form1() { InitializeComponent(); Assembly assembly=Assembly.GetExecutingAssembly();//获取当前主程序集 Rm=new ResourceManager("ResourceUserinfo.Userinfo",assembly);//实例化资源管理类 photo.iamge=(Image)rm.GetObjetct("Photo"); username.Text=rm.GetString("Username"); sex.Text=rm.GetString("Sex"); birthday.Text=rm.GetString("Birthday"); salary.Text=rm.GetString("Salary"); } |
运行这段代码,就可以取出资源文件内容。
为.Net程序集添加资源相关推荐
- Qt Creator添加资源
添加资源有两种方法.一种是直接添加系统提供的资源文件,然后选择所需图标.另一种是自己写资源文件. 第一种:1.新建Qt Resources file,将它命名为menu.其他默认. 2.添加完后如下图 ...
- Qt中为工程添加资源文件、给按钮添加图片
Qt中为工程添加资源文件.给按钮添加图片 1.使用QIcon类.代码如下: QIcon icon;icon.addFile(tr("res/icon/wall.png"));ui- ...
- C#怎么给新建的winform程序添加资源文件夹Resources
小菜鸟开始学习WinForm程序 别人的项目都有资源文件夹放图片之类的,我的就是没有... 于是找啊找,找到了解决方案:放了一个图片进去...出现Resources 新建WinForm项目没有Reso ...
- 直接在apk中添加资源的研究
原文 http://blog.votzone.com/2018/05/12/apk-merge.html 之前接手过一个sdk的开发工作,在开发过程中有一个很重要的点就是尽量使用代码来创建控件,资源文 ...
- MFC 错误异常,用vs添加资源并为资源定义类后报错:error C2065 : 未声明的标识符...
添加了一个Dialog资源,修改了ID之后右击资源添加了一个类,在类里面有一个成员变量: // 对话框数据 enum { IDD = IDD_GETIN }; 而在编译过程中出现报错,错误代号 ...
- VC2010“添加资源-引入JPG图片”会改变图片大小
结论: 通过VC2010添加JPG图片(添加资源->引入jpg图片)会改变图片大小. 本身只是为了想给对话框添加一个背景图片,试了下bmp的,都没有问题. 为了测试下是否可以加载(用LoadIm ...
- Win32窗体应用程序如何添加资源文件?
Win32窗体应用程序如何添加资源文件? 上一篇文章介绍了:如何创建一个最简单的Windows窗体应用程序. 按照上一篇文章的介绍,我们的HelloApp项目对应如下的窗体应用程序: 这一篇文章中,我 ...
- qt添加资源文件后编译失败,提示Qt:Error:No rule to make target ’ … /…/??.png’,needed by ‘debug/qrc_qrc.cpp’ stop
提要 项目本来编译没有问题,资源文件忘记添加了,于是添加资源文件后,编译没有通过,提示错误:Qt:Error:No rule to make target ' - /-/??.png',needed ...
- QT打印窗口、退出、设置字体及颜色、设置时间、控件实现系统函数、添加资源文件(菜单图片)、工具栏添加图片
打印窗口 #include <QPrintDialog> 退出 QObject::connect(ui->exitAction, SIGNAL(triggerd()), this, ...
最新文章
- 解吧源码解析重点看withWeight
- 移动互联网用户的心理需求【转载】
- 在线测试所有浏览器的兼容性
- linux查看内核版本、系统版本、系统位数(32or64)
- jvm性能调优实战 -60 线上系统的JVM参数优化、GC问题定位排查、OOM分析解决
- Gradle 设置 本地maven仓库及发布mavenLocal()路径的方法
- 【MFC】具有提示功能的工具栏
- 665. 非递减数列 golang 切片越界问题的探讨(二)
- 取出重复记录的第一条
- 每天一个linux命令:【转载】less命令
- MATLAB中ASCII码的举例
- blender源代码分析----第三方库的说明
- Arm 公司推出了 Mbed linux OS
- 解决vscode进行chrome调试时报错:localhost拒绝连接请求
- MAP(maximum a posteriori)
- 服务器ibmc无法加载js文件,weUI应用之JS常用信息提示弹层的封装
- Windows Installer无法启动或不见了的解决方法
- 【英语天天读】优秀的标准
- c语言在规定时间内跳出循环,do while死循环如何在规定时间内跳出
- The requested URL was not found on the server. If you entered the URL manually please check your spe
热门文章
- 关于Socket通信客户端是否需要绑定端口号
- 【物料钢卷识别与定位】:1.读取数据(获取原始数据)
- LaneATT调试笔记
- 基于VLC的rtsp服务器linux平台搭建
- 设置IDEA最多同时打开的窗口数量为100
- Linux下使用diff和patch制作及打补丁(已经实践可行!)
- Blender从头到尾创建一辆宝马轿车视频教程
- 风格化手绘纹理包 CGTrader – Stylized Mix Vol. 41 – Hand Painted Texture Pack
- c语言实现memcpy
- 从JoinBatchGroup 代码细节 来看Rocksdb的相比于leveldb的写入优势