Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding resources in Visual Studio

In Visual Studio I have several ways to include resources into my project:

  1. Solution Explorer → My Project → Right Click → Properties → Resources → Add Resource
  2. Copy file to solution directory → Solution Explorer → Show all Files → Right Click → Include in Project → Right Click → Properties → Build Action → Resource
  3. Copy file to solution directory → Solution Explorer → Show all Files → Right Click → Include in Project → Right Click → Properties → Build Action → Embedded Resource
  4. Some more?

My questions are:

  • What are the differences of these resources?
  • How can I access them by code (C#)?
  • Is it possible to add new resources by code?
like image 327
Wernfried Domscheit Avatar asked Jan 21 '15 12:01

Wernfried Domscheit


People also ask

What is a resource in Visual Studio?

Applies to: Visual Studio Visual Studio for Mac Visual Studio Code. Resource files are files that are part of an application but are not compiled, for example icon files or audio files. Since these files are not part of the compilation process, you can change them without having to recompile your binaries.

How do I view resources in Visual Studio?

Any managed resources you want to edit must be linked resources and Visual Studio resource editors don't support editing embedded resources. To view a managed resource in a resource editor, in Solution Explorer, double-click the resource, for example, Bitmap1. bmp, and the resource opens in the appropriate editor.

What is resource in Visual Basic?

Microsoft defines a resource as "any nonexecutable data that is logically deployed with an application." The easiest way to manage resource files in your project is to select the Resources tab in the project properties.

What are resources in C#?

Resources is a very useful namespace that allows you to create and store culture-specific resources used in an application (for example, you can have Spanish and English resources). Resources allows you to place culture-specific items inside satellite files, rather than directly in your main application.


1 Answers

Storage

For #1, the resource that you add is stored in XML format in a file named Resources.resx, typically located in the Properties subfolder of a WinForms or WPF application that is created using the default Visual Studio templates.

For #2 and #3, the resource (file) is included in the project (ie. the Visual Studio project knows about the file, it will be added to source control if that is applicable for the project, etc), the difference is in how the compiler includes the contents of the file as part of the resulting assembly. #2 is typically used for WPF applications; #3 for WinForms applications.


Access

#1 (Resources.resx)

The resources are accessed via an auto-generated class called Resources. For example, if you add a bitmap resource named MyBitmap you can access that as follows:

System.Drawing.Bitmap bitmap = Properties.Resources.MyBitmap;

#2 (Build Action = Resource)

The resources can be referenced from XAML (markup) or code. For XAML, several of the standard controls support resource references. For example, the Image control has a Source property that by default references an embedded resource. To reference a resource file named "wpf.jpg" contained in the root of your WPF project:

<Image Source="wpf.jpg" />

If the file was in a subfolder named "images":

<Image Source="images/wpf.jpg" />

To access these resources from code, you use the GetResourceStream method of the Application class, passing a reference to the desired resource in the form of a pack URI. Using the file in the above example:

Uri path = new Uri("images/wpf.jpg", UriKind.Relative);
StreamResourceInfo ri = Application.GetResourceStream(path);
Stream data = ri.Stream;

Once you have the stream you can do what you want with it.

#3 (Build Action = Embedded Resource)

You need to get a reference to the assembly containing the resource, then call the GetManifestResourceStream method to obtain a stream for it. What you do with the stream depends on the type of resource you're dealing with. For example, this will create a bitmap from a named resource:

Bitmap bitmap = new Bitmap(
    System.Reflection.Assembly.GetEntryAssembly()
    .GetManifestResourceStream("resourcename"));

Getting the right resource name can be tricky. It is generally a concatenation of the assembly name, and the folder and file name of the resource. For example, a file named "MyBitmap.bmp" in a folder named "Resources" in a project named "WindowsFormsApplication1" would be compiled to a resource named WindowsFormsApplication1.Resources.MyBitmap.bmp. That's the string you would pass to the GetManifestResourceStream method.


Adding new resources

As the resources are compiled into the assembly (EXE or DLL), adding new resources cannot be done without recompiling the assembly. The only programmatical way of doing this that I know of is to use a NuGet package called Mono.Cecil.

like image 63
Steven Rands Avatar answered Sep 21 '22 05:09

Steven Rands