2011-07-12 24 views
8

Tengo un programa que contiene una serie de iconos en una carpeta "Iconos" (que se incluyen en el proyecto con Build Action = Resource).¿Dónde están escondidos mis recursos?

En XAML puedo acceder a estos iconos con código como <Image Source="../Icons/name.png"/> (".." porque el XAML está en una subcarpeta diferente); sin embargo, quiero usar la misma imagen en algún código de WinForms en el mismo proyecto. Por desgracia,

GetType().Assembly.GetManifestResourceStream("Icons/name.png"); 

vuelve null y

GetType().Assembly.GetManifestResourceNames() 

sólo enumera un manojo de * .resources archivos (uno por cada Resx y uno llamado * .g.resources). Entonces, ¿cómo se supone que debo obtener la transmisión de imágenes?

Respuesta

7

que supone que desde que incluía las imágenes directamente en mi proyecto que podía leer directamente. Pero gracias a la respuesta de Jack, pude descubrir que están ocultos dentro de un "archivo de recursos" llamado "ProgramName.g.resources" dentro del ensamblado. Para leer la imagen, primero es necesario cargar el archivo de recursos y luego buscar el archivo de imagen dentro del archivo de recursos.

ResourceSet.GetObject distingue entre mayúsculas y minúsculas, pero la ruta de la imagen y el nombre del archivo se convirtieron a minúsculas por algún motivo, así que llamo al ToLowerInvariant en el nombre de la ruta. Aquí está mi solución:

private Stream GetGlobalResourceByPath(Assembly assembly, string path) 
{ 
    string name = assembly.GetManifestResourceNames().Where(n => n.EndsWith(".g.resources")).First(); 
    Stream outerStream = assembly.GetManifestResourceStream(name); 
    ResourceSet resources = new ResourceSet(outerStream); 
    return resources.GetObject(path.ToLowerInvariant()) as UnmanagedMemoryStream; 
} 

No estoy seguro de lo caro que es para construir una ResourceSet. Si es costoso y desea recuperar múltiples recursos, entonces debe almacenar en caché y reutilizar el objeto ResourceSet.

Por favor, deje un mensaje si sabe por qué las imágenes terminan dentro del archivo * .g.resources. ¿Visual Studio eligió este nombre? ¿Es teóricamente posible colocar imágenes directamente en un ensamblaje, o los ensamblajes solo pueden contener "ResourceSets"?

+0

No me molesté con los archivos de recursos cuando quería incluir imágenes, javascript, css etceteras. Los tuve directamente en el proyecto con una acción de creación de 'Recurso incrustado' y, por lo tanto, no tuve que perder el tiempo con conjuntos de recursos. –

2

puede encontrar algo de ayuda de:

http://blog.devarchive.net/2007/12/net-assembly-resource-browser-test.html

http://msdn.microsoft.com/en-us/library/system.io.unmanagedmemorystream.aspx

En el primer enlace, se puede encontrar una manera de obtener el recurso que es tipo de UnmanagedMemoryStream, entonces debería encontrar una forma de convertir la transmisión al tipo que desee.

Espero que te ayude!


foreach (var resourceName in ThemeList.Current.GetType().Assembly.GetManifestResourceNames()) 
{ 
       var resourceStream = GetType().Assembly.GetManifestResourceStream(resourceName); 
       ResourceSet resources = new ResourceSet(resourceStream); 
       IDictionaryEnumerator enu = resources.GetEnumerator(); 
       while (enu.MoveNext()) 
       { 
        Console.WriteLine(enu.Key); // Key is the resource name and Value is UnmanagedMemoryStream 
       } 
} 
+1

Eso fue útil, gracias. Mi respuesta a continuación. – Qwertie

Cuestiones relacionadas