主要内容:
在.NET环境下如何给程序及中嵌入资源。主要讲述如何嵌入,如何使用两部分内容。
使用的命名空间和类:
System.Resources namespace
System.Resources.ResourceWriter class
System.Resources.ResourceManager class
使用的工具:
Visual Studio.NET 2003
.NET Framework Ver1.1
问题的由来:
一般来说,一个以用程序中要包含有图片、图标、字符串等多种资源。这些资源如果放在程序外边,很可能会因为某些原因(比如环境变量)给编程造成困难。下面的方法就是怎样把我们使用的资源变成一个文件,再嵌入到可执行程序或者程序集中的方法。
第一部分 制作一个资源文件
我们首先打开Visual Studio.NET 创建一个名叫Resource_Assembly的空白解决方案。然后我们在这个解决方案中添加一个控制台项目叫做ResourceWriter。
下面在main.cs文件中添加引用:
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Resources;
在Mian函数中编辑代码:
[STAThread]
static void Main(string[] args)
{
try
{
//声明ResourceWriter对象,将资源存入MyResources.dll文件中
System.Resources.ResourceWriter rw = new System.Resources.ResourceWriter("MyResources.resources");
//载入图片
System.Console.WriteLine("Reading Jpeg file......");
System.Drawing.Image Img = System.Drawing.Image.FromFile(@"E:/My Documents/Resource_Assembly/ResourceWriter/Resources/MaTT&Anders.jpg");
//添加资源
System.Console.WriteLine("Adding a Image as a resource......");
rw.AddResource("MyPic",Img);
//声明字符串
string Mystr = "I like Eric Claption, he is my hero.";
//添加字符串资源
System.Console.WriteLine("Adding a string......");
rw.AddResource("MyString",Mystr);
rw.Close();
}
catch
{
System.Console.WriteLine("Here is a error,writting file failed.");
rw.Close();
System.Threading.Thread.Sleep(2000);
return;
}
System.Console.WriteLine("Operation complete.Press Enter to exit");
System.Console.Read();
}
}
其中,rw对象是一个System.Resources.ResourceWriter的实例,用来把各种资源写入资源文件。资源文件的名称是MyResources.resources。然后读入了一个Jpeg文件,并保存到MyResources.resources资源文件中。Jpeg文件的路径请根据实际情况更改。然后又向MyResources.resources资源文件中写入了一个字符串。
在System.Resources.ResourceWriter类中有一个重要的方法叫做AddResource。这个方法有两个参数,第一个参数是这个资源的资源名称,用于以后提取资源时使用。后面的参数就是要添加的资源对象的引用。
这个项目编译之后运行,就会在当前程序文件家中产生一个名叫MyResources.resources的资源文件。这个就是我们想要的。
第二部分 将资源文件嵌入程序集中并使用
下面我们再在解决方案中加入一个新的工程ResourceConsumer。这个工程是WinForm型的。在ResourceConsumer工程中加入我们刚刚创建好的MyResources.resources文件。在MyResources.resources项目上点鼠标右键,选择属性,选择生成操作的下拉框,选择“嵌入的资源”。只有这样编译器才会把资源文件嵌入到当前的可执行文件或程序集中。
下一步,就是如何调用这些资源了。这一步需要用到反射。通过反射中Assembly对象的GetExecutingAssembly方法得到当前程序本身的实例引用。然后创建一个ResourceManager类型的对象rm。
//通过反射得到资源程序集
System.Reflection.Assembly asm = Assembly.GetExecutingAssembly();
//初始化资源管理对象
rm = new ResourceManager("ResourceConsumer.MyResources",asm);
创建ResourceManager对象时请注意一个问题。在程序集内部资源也是拥有命名空间的,一般的形式是:应用程序命名空间.用户定义的资源文件名称.resources。ResourceManager在对象创建的时候,会根据用户给出的第一个参数"ResourceConsumer.MyResources"字符串后面自动加上”.resources”,所以请不要刻意的人工加上”.resources”否则ResourceManager会产生异常。
如果您对您的资源到底在哪个命名空间下不太清楚,您可以使用.NET Framework SDK 附带的工具ildasm.exe查看程序集中的原数据部分。您将清楚地看到您的资源命名空间。
使用程序集内部的资源,可以通过调用ResourceManager类中的GetObject方法实现。
//从资源中提取字符串并显示
this.pictureBox1.Image = (Image)rm.GetObject("MyPic");