How can I discover the "path" of an embedded resource?

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.

152087 次浏览

我猜测您的类位于不同的名称空间中。解决这个问题的规范方法是使用 resources 类和强类型资源:

ProjectNamespace.Properties.Resources.file

使用 IDE 的资源管理器添加资源。

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

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

我发现自己每次都忘记了如何做到这一点,所以我只是在一个小班上包装了两个我需要的一行程序:

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

资源的名称是名称空间加上文件路径的“伪”名称空间。“伪”名称空间是由子文件夹结构使用(反斜杠)而不是。(点)。

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.

我使用以下方法获取嵌入式资源:

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

然后我用项目中的路径称之为:

GetResourceStream(@"DirectoryPathInLibrary/Filename");