Question

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.

Was it helpful?

Solution

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

System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceNames();

OTHER TIPS

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();
    }
}

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.

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")

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top