How to add resources in separate folders? - c#

When I try to add a resource at the resource designer by clicking "Add an existing item",the item is placed in the folder "Resource".
The problem is that if I create a new directory in the Resource directory and place the resources there,I get a compiler error that the files cannot be found.
I can't put all resources in one folder,because I have to add 2500 images and some of them match their names.

You do not need to add the images under the Resources folder. You can add the images to any folder you wish, and then set the build action for the images to "Embedded Resource". That way they will be compiled into the assembly as resources. I don't know if there are performance issues coming into play when it is a large number of images though...
Update: more in detail:
Add the folders and image files as project items to the project (so that you can see each folder and the images within it in the Solution Explorer)
Set the Build Action property of each of the image files to "Embedded Resource" (you can do this for multiple files at the same time; just select all the image files in the solution explorer).
This will cause the image files to be compiled into the assembly as resources. Each file will be assigned a resource name following this pattern: <root namespace for the assembly>.<folder name>.<image file name>. You can load an image using this code:
using(Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("<root namespace for the assembly>.<folder name>.<image file name>"))
{
pictureBox1.Image = Image.FromStream(stream);
}

Create a new resource file (in following example I called it Images01 in folder resx)
Create a custom resource manager class and initialize it to to point to this file just created
ResourceManager rm = new ResourceManager("ROOTNAMESPACE.resx.Images01",
System.Reflection.Assembly.GetExecutingAssembly());
Implement the method to GetImage
public static Image GetImage(string fileName)
{
Stream stream = GetResourceStream(fileName);
Image image = null;
if (stream != null)
{
image = Image.FromStream(stream);
}
return image;
}
Add images to this resx file
And then you can use it in your code as follows
this.picProject.Image = Resources.GetImage("ImageName.png");
Hope it helps

Related

Get a list of all resources from an assembly

I have a folder with Resources and want to get a list with all paths.
If I set them to an embedded resource, I can get them via
var resources = Assembly.GetExecutingAssembly().GetManifestResourceNames();
When follwing this answer https://stackoverflow.com/a/1935035/6229375, I shouldn't use embedded resource anymore or I'm doing something wrong?
From the following blog post:
Files marked with build action of “Resource” are added to a special
resx file called ProjectName.g.resx. This file is generated during the
build, it is not part of the project. You can access content of the
‘Resource’ files by creating an instance of ResourceManager and
calling GetStream(filename). Additionally, in WPF applications you can
access these resources via Application.GetResourceStream() in C# and
via things like in XAML.
var resourceManager = new ResourceManager("ConsoleApp5.g", Assembly.GetExecutingAssembly());
var resources = resourceManager.GetResourceSet(CultureInfo.CurrentUICulture, true,
true);
foreach (var res in resources)
{
System.Console.WriteLine(((DictionaryEntry)res).Key);
}
where ((DictionaryEntry)res).Value will be Stream.
The question and the accepted solution are for "Resource" files, and in my cases I needed "Embedded Resource" files. For that, there is a built-in method: Assembly.GetManifestResourceNames
foreach(string resourceName in Assembly.GetExecutingAssembly().GetManifestResourceNames())
{
Console.WriteLine(resourceName);
}

Load Embedded Resources from dynamically loaded assemblies

I have Class Library project that creates a dll that I side load into my main application dynamically. The main application contains API calls that I use and one of the calls is to load an icon image into a WPF button. I provide "pack://application:,,,/NamespaceOfMyDll;Component/Resources/embeddedresource.ico"
as my URI source and following is the code that tries to load this image
var logo = new BitmapImage();
logo.BeginInit();
logo.UriSource = new Uri(source);
logo.EndInit();
The image is an embedded resource of the dll that I am side loading. Doing this throws an exception saying the source is not found.
The project that is trying to load the image has no reference to the dll that I am side loading.
Is there a way to load the image without having to put it in the main application project?
Here's a workaround you can go with :
When you add images to the class's resource(I mean in Resources.resx file of the class), create public variables for each resource you add/you want to access. Sample :
public static class TestClass
{
public static Bitmap Image1 { get { return Resource1.Image1; } }
public static Bitmap Image2 { get { return Resource1.Image2; } }
}
Now, let's move on to loading the .dll into the main project :
Assembly Mydll = Assembly.Load("dll path here");
Type MyLoadClass = MyDALL.GetType("dllAssemblyName.ClassName");
object obj = Activator.CreateInstance(MyLoadClass);
Now, try to access the Bitmap variables :
Bitmap img1 = (Bitmap)obj.GetType().GetField("Image1").GetValue(obj);
///use the bitmap the way you want :)
Hope this helps
Using Build Action "Resource" instead of "Embedded Resource" solved the issue.
"Resource is for WPF applications when you want to use uri's to link to resources. Embedded resource is an embedded resource for WinForms applications that should be accessed via a ResourceManager."
https://social.msdn.microsoft.com/Forums/vstudio/en-US/29b6d203-18fb-40b0-a01f-d5b787ccf3be/build-action-resource-vs-embedded-resource?forum=netfxbcl

Is it possible to embed binary data in a .NET assembly

Is it possible to embed binary data (as a resource, or by some other mean) in the C# assembly and then read the binary data from assembly during run-time and write it as a file.
I am making a DRM application and purpose is that the data must be hidden in the assembly as embedded resource, or a password protected ZIP file. So, I will try to embed the resource and if not possible then will look for a ZIP / UN-ZIP library with password protection to save DRM data.
I am writing a program in C# in which should have a binary data and it is added in the assembly during compile just like images, icons are added in assembly when we compile, and then when the assembly is executed by user then the binary data is read and saved as an external file.
Is it possible? then how to do it?
Yes. If you are using resources, you can include files too, which are represented as a byte array. Else you can include a file and set the Build Action to Embedded Resource, which include it as a resource too, which you can manually read.
public byte[] ExtractResource(Assembly assembly, string resourceName)
{
if (assembly == null)
{
return null;
}
using (Stream resFilestream = assembly.GetManifestResourceStream(resourceName))
{
if (resFilestream == null)
{
return null;
}
byte[] bytes = new byte[resFilestream.Length];
resFilestream.Read(bytes, 0, bytes.Length);
return bytes;
}
}
Then use it like this:
byte[] bytes = this.ExtractResource( Assembly.GetExecutingAssembly()
, "Project.Namespace.NameOfFile.ext"
);
yeah, its possible. Just add the file in the project, Select the file, Go to property and select Embedded Resource in Build Action property.
Here's the code=
private Stream GetStream(string fileName)
{
var asm = Assembly.GetExecutingAssembly();
Stream stream = asm.GetManifestResourceStream("NameSpace." + fileName);
return stream;
}
For clarification of sv88erik doubts-
as you can see in picture here, embedded resources are a part of the assembly itself and having a name as NameSpace.FileName
Background: When you build your application, the linked and embedded resource data is compiled directly into the application assembly (the .exe or .dll file).
To access the resources, use the class Resources contained in Resources.Designer.cs which is nested under the Resources.resx file in Solution Explorer. The Resources class encapsulates all your project resources into static readonly get properties. For example, a string resource “Bill” is accessed by Properties.Resources.Bill. You can access a Text file resource also as a string property. Binary files are referenced as properties of type byte[].
Double-click Resources.resx. Select Add Resource/Add Existing File and scroll to the file you want to be included.
For binaries, the class Resources has a property of type byte[] that is named after the included file. Assume the file name to be MyApp.dll, then the property should have the name MyApp. You find the exact name in the code file Resources.Designer.cs nested under the Resources.resx file in Solution Explorer.
You can access the resource as Properties.Resources.MyApp. For example, you can save the resource as a binary file with File.WriteAllBytes(PathAndName, Properties.Resources.MyApp);.

Access to Resources

I've C# project and it has Resources folder. This folder has some of txt files. This files have various file names.
I'm taking file names from any source as string variable. For example I have fileName string variable and test.txt file in Resources folder:
string fileName = "test.txt";
When I want to access this file as like below, I can:
WpfApplication.Properties.test.txt;
But, When I want to access it by this code, I can't.
WpfApplication.Properties.fileName;
I want to use fileName string variable and access this text file.
What can I do to access it?
Thanks in advance.
Edit :
I change form of this question:
I've string variable assigned any text file name. For example; I have a.txt, b.txt, c.txt, d.txt, etc.. I'm taking this file name as string variable (fileName) via some loops. So, I took "c.txt" string. And, I can access this file by code in below:
textName = "c.txt";
fileName = "../../Resources\\" + textName;
However, when I build this project as Setup Project and install .exe file to any PC, there is no "Resources" folder in application's folder. So,
../../Resources\
is unavailable.
How can I access Resources folder from exe file's folder?
You need to add a Resource File to your project wich has the extension .resx/.aspx.resx. You will then be able to double click on this file and edit the required resources/resource strings. To do this right click on Project node in Solution Explorer > Add > New Item > Resource File. Let us assume you have added a file called ResourceStrings.resx to the Properties folder and added a resource string with key name MyResourceString, to access these strings you would do
string s = Properties.ResourceStrings.MyResourceString;
I hope this helps.
I would strongly recommend you taking a look at: http://msdn.microsoft.com/en-us/library/aa970494.aspx
If your text files have build action set as Resource you can locate them in code like:
(assuming the file name is fileName and its located in Resources folder)
Uri uri = new Uri(string.Format("Resources/{0}", fileName), UriKind.Relative);
System.Windows.Resources.StreamResourceInfo info = Application.GetResourceStream(uri);
Then you can access info.Stream to get access to your file.

How to set relative path to Images directory inside C# project?

I am working on C# project i need to get the images from Images directory using relative path. I have tried
var path = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + #"\Images\logo.png";
var logoImage = new LinkedResource(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)+#"\Images\logo.png")
But no luck with these...
I have made the images to be copied to output directory when the program is running but it doesn't pickup those images.
If you are using LinkedResource() in C# it is most likely not to pickup your relative URI or the file location.
You can use some extra piece of code
var outPutDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase);
var logoimage = Path.Combine(outPutDirectory, "Images\\logo.png");
string relLogo = new Uri(logoimage).LocalPath;
var logoImage = new LinkedResource(relLogo)
Now it will pickup your relative path, convert this to absolute path in memory and it will help you get the images.
First, add those image file to your project (create an Image folder is a good idea)
Second, select the image in your solution manager, and view the property window.
And then, change the "copy to output folder" to "always" or "copy when update".
PS. My IDE is Trad. Chinese so I can not ensure the correct keywords in your language.
I would make sure that the Images directory is in the output folder.
I usually use Assembly.GetExecutingAssembly().Location to get the location of my dll.
However, for images, I usually use the Resources page/collection in the project's Properties page. Here is more information about it. Putting the image in the project's Resource would automatically give you an easy way to access it.
For more information about GetExecutingAssembly: MSDN Page
if u want to display images in your folder using your application use an array and put all pictures in ur folder into array. then you can go forward and backward.
string[] _PicList = null;
int current = 0;
_PicList = System.IO.Directory.GetFiles("C:\\Documents and Settings\\Hasanka\\
Desktop\\deaktop21052012\\UPEKA","*.jpg");
// "*.jpg" will select all
//pictures in your folder
String str= _PicList[current];
DisplayPicture(str);
private void DisplayPicture(string str)
{
//throw new NotImplementedException();
BitmapImage bi = new BitmapImage(new Uri(str));
imagePicutre.Source = bi; // im using Image in WPF
//if u r using windows form application it must be a PictureBox i think.
label1.Content = str;
}

Categories