2008-08-26 17 views
81

Estoy almacenando un PNG como un recurso incrustado en un ensamblaje. Desde dentro del mismo conjunto Tengo algo de código como este:¿Cómo puedo descubrir la "ruta" de un recurso incrustado?

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

El archivo, denominado "file.png" se almacena en la carpeta de "Recursos" (dentro de Visual Studio), y se marca como un recurso incrustado.

El código de falla con una excepción diciendo:

Recursos MyNamespace.Resources.file.png no puede ser encontrado en MyNamespace.MyClass clase

que tienen idéntico código (en un montaje diferente, cargando un recurso diferente) que funciona. Entonces sé que la técnica es sólida. Mi problema es que termino pasando mucho tiempo tratando de descubrir cuál es el camino correcto. Si pudiera simplemente consultar (por ejemplo, en el depurador) el ensamblado para encontrar la ruta correcta, eso me ahorraría un montón de dolores de cabeza.

Respuesta

156

Esto le dará una matriz de cadenas de todos los recursos:

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

¡Bastante útil! ¡Gracias! –

15

Supongo que su clase está en un espacio de nombres diferente. La forma canónica para resolver este sería el uso de la clase de recursos y un recurso inflexible:

ProjectNamespace.Properties.Resources.file 

utilizar el Administrador de recursos del IDE para agregar recursos.

+0

Tienes razón, mi clase está en un espacio de nombres diferente. Parece que la carpeta de recursos vive bajo el espacio de nombres especificado como el espacio de nombres predeterminado en la configuración del proyecto, que por diversas razones no es el espacio de nombres del que forma parte esta clase. Sospecho que tiene razón también acerca del uso de un enfoque diferente por completo, pero como necesito ser consistente con el código heredado, eso escapa a mi control. – Rob

+0

Esto capta el recurso, no su ruta de archivo. –

+0

@UchihaItachi Es por eso que ofrecí esta respuesta explícitamente como otra forma (y posiblemente la canónica) de resolver el * problema subyacente * en lugar de responder la pregunta palabra por palabra (que ya tiene una respuesta en cualquier caso). –

41

me encuentro olvidar cómo hacer esto cada vez que así lo que sólo envolver los dos de una sola línea que necesito en una pequeña clase:

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

el nombre del recurso es el espacio de nombres más el espacio "pseudo" nombre de la ruta de acceso al archivo. El espacio de nombre "pseudo" se crea mediante la estructura de la subcarpeta utilizando \ (barras diagonales inversas) en lugar de. (puntos)

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

La siguiente llamada:

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

devolverá el flujo de my.xml situado en los recursos de estructura de carpetas \ xml en el espacio de nombres: my.namespace.

+4

También los guiones ('-') en las carpetas se reemplazan por guiones bajos ('_'). Puede haber otros símbolos también. Me gustaría ver cómo lo está haciendo el compilador para que podamos usar el mismo método. –

5

que utilizar el siguiente método para agarrar recursos incrustados:

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

entonces yo llamo a esto con la ruta en el proyecto:

GetResourceStream(@"DirectoryPathInLibrary/Filename") 
Cuestiones relacionadas