123

I am storing a PNG as an embedded resource in an assembly. From within the same assembly I have some code like this:

Bitmap image = new Bitmap(typeof(MyClass), "Resources.file.png"); 

The file, named "file.png" is stored in the "Resources" folder (within Visual Studio), and is marked as an embedded resource.

The code fails with an exception saying:

Resource MyNamespace.Resources.file.png cannot be found in class MyNamespace.MyClass

I have identical code (in a different assembly, loading a different resource) which works. So I know the technique is sound. My problem is I end up spending a lot of time trying to figure out what the correct path is. If I could simply query (eg. in the debugger) the assembly to find the correct path, that would save me a load of headaches.

5 Answers 5

220

This will get you a string array of all the resources:

System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceNames(); 
Sign up to request clarification or add additional context in comments.

1 Comment

Hey, How can I get the Resource Folder path to assign it as the root Dir for my embedded http server?
52

I find myself forgetting how to do this every time as well so I just wrap the two one-liners that I need in a little class:

public class Utility { /// <summary> /// Takes the full name of a resource and loads it in to a stream. /// </summary> /// <param name="resourceName">Assuming an embedded resource is a file /// called info.png and is located in a folder called Resources, it /// will be compiled in to the assembly with this fully qualified /// name: Full.Assembly.Name.Resources.info.png. That is the string /// that you should pass to this method.</param> /// <returns></returns> public static Stream GetEmbeddedResourceStream(string resourceName) { return Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName); } /// <summary> /// Get the list of all emdedded resources in the assembly. /// </summary> /// <returns>An array of fully qualified resource names</returns> public static string[] GetEmbeddedResourceNames() { return Assembly.GetExecutingAssembly().GetManifestResourceNames(); } } 

1 Comment

I would advise GetEmbeddedResourceStream(string resourceName) returns Stream? rather than Stream since it can return a null.
20

I'm guessing that your class is in a different namespace. The canonical way to solve this would be to use the resources class and a strongly typed resource:

ProjectNamespace.Properties.Resources.file 

Use the IDE's resource manager to add resources.

4 Comments

You are right, my class is in a different namespace. It seems that the Resources folder lives under the namespace specified as the default namespace in the project configuration, which for various reasons isn't the namespace that this class is part of. I suspect you're correct also about using a different approach entirely, but as I need to be consistent with legacy code, that's beyond my control.
This grabs the resource - not it's file path.
@UchihaItachi That's why I offered this answer explicitly as another (and arguably the canonical) way of solving the underlying problem rather than answering the question verbatim (which already has an answer at any rate).
@UchihaItachi The question also tells the problem the asking person is facing, what his approach is and how he has tried so far. Although Rudolph does not directly answer the question, he addresses another approach to solve the problem. In most cases, this approach is more convenient, safe, and common. This answer is helpful. I just don't understand why you have to try to shut down people's answers. Vote Up/ Vote Down buttons are there for a reason.
9

I use the following method to grab embedded resources:

protected static Stream GetResourceStream(string resourcePath) { Assembly assembly = Assembly.GetExecutingAssembly(); List<string> resourceNames = new List<string>(assembly.GetManifestResourceNames()); resourcePath = resourcePath.Replace(@"/", "."); resourcePath = resourceNames.FirstOrDefault(r => r.Contains(resourcePath)); if (resourcePath == null) throw new FileNotFoundException("Resource not found"); return assembly.GetManifestResourceStream(resourcePath); } 

I then call this with the path in the project:

GetResourceStream(@"DirectoryPathInLibrary/Filename"); 

Comments

5

The name of the resource is the name space plus the "pseudo" name space of the path to the file. The "pseudo" name space is made by the sub folder structure using \ (backslashes) instead of . (dots).

public static Stream GetResourceFileStream(String nameSpace, String filePath) { String pseduoName = filePath.Replace('\\', '.'); Assembly assembly = Assembly.GetExecutingAssembly(); return assembly.GetManifestResourceStream(nameSpace + "." + pseduoName); } 

The following call:

GetResourceFileStream("my.namespace", "resources\\xml\\my.xml") 

will return the stream of my.xml located in the folder-structure resources\xml in the name space: my.namespace.

2 Comments

Also dashes ('-') in the folders are replaced with underscores ('_'). There might be other symbols as well. I'd like to see how the compiler is doing it so we can use the same method.
Boyko is right brackets ( and ) are another that is replaced.. Here is a crude solution... private static List<string> ReplaceWithUnderscore = new List<string>{ "(", ")", "-" }; public static string WrangleToResourceString(string rawString) { var result = rawString; foreach (var replace in ReplaceWithUnderscore) { result = result.Replace(replace, "_"); } return result; }

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.