2009-09-07 8 views
27

Ich habe ein Bild in einer C# -WPF-App, deren Build-Aktion auf 'Ressource' festgelegt ist. Es handelt sich lediglich um eine Datei im Quellverzeichnis, die der Ressourcensammlung der App nicht über den Drag & Drop-Eigenschaften-Dialog hinzugefügt wurde. Ich versuche es als Stream zu schreiben, aber ich kann es nicht öffnen, obwohl ich ein paar Variationen von Punkten, Schrägstrichen, Namespaces und scheinbar alles andere versucht habe.Ressource aus Assembly als Stream

Ich kann darauf zugreifen, um woanders entweder in XAML mit "pack: // application: ,,,/Resources/images/flags/tr.png" zu verwenden, aber ich kann nicht in einem Stream, der es enthält.

Die meisten Orte scheinen Gebrauch zu sagen

using(BinaryReader reader = new BinaryReader(System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("ResourceBlenderExpress.Resources.images.flags.tr.png"))) { 
    using(BinaryWriter writer = new BinaryWriter(File.OpenWrite(imageFile))) { 
     while((read = reader.Read(buffer, 0, buffer.Length)) > 0) { 
      writer.Write(buffer, 0, read); 
     } 
     writer.Close(); 
    } 
    reader.Close(); 
} 

Was ich kein Glück mit gehabt haben.

Antwort

23

GetManifestResourceStream ist für traditionelle .NET-Ressourcen das heißt diejenigen, die in RESX-Dateien verwiesen. Diese sind nicht dieselben wie WPF-Ressourcen, d. H. Diejenigen, die mit einer Build-Aktion von Resource hinzugefügt wurden. Um auf diese zuzugreifen, sollten Sie Application.GetResourceStream verwenden und das entsprechende Paket: URI übergeben. Dies gibt ein StreamResourceInfo-Objekt zurück, das über eine Stream-Eigenschaft verfügt, um auf die Daten der Ressource zuzugreifen.

+0

Danke, ich hätte das nie gefunden. :) – Echilon

1

Sie müssen die Methode Close() nicht aufrufen, sie wird am Ende der using-Klausel automatisch von Dispose() aufgerufen. So Ihr Code könnte wie folgt aussehen:

using(BinaryReader reader = new BinaryReader(System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("ResourceBlenderExpress.Resources.images.flags.tr.png"))) 
using(BinaryWriter writer = new BinaryWriter(File.OpenWrite(imageFile))) 
{ 
    while((read = reader.Read(buffer, 0, buffer.Length)) > 0) 
    { 
     writer.Write(buffer, 0, read); 
    } 
} 
+0

Wie beantwortet das die Frage? –

+0

Wirklich? Nützlicher Einblick, wenn es wahr ist. Ich dachte immer, dass das explizite Aufrufen von Close für Streams/Dateien besser ist. – Echilon

+0

Die Verwendung der Using-Anweisung ruft explizit die Dispose-Methode des Streams auf, die implizit die Close-Methode davon aufruft. Auch die using-Anweisung enthält immer das "used" -Objekt, auch wenn eine Ausnahme ausgelöst wird, so dass die Verwendung eine allumfassende, fast fehlerfreie Aussage ist. – BeardinaSuit

6

Wenn ich Sie recht verstehe, haben Sie ein Problem, das der Ressource Strom zu öffnen, weil Sie nicht ihren genauen Namen wissen? Wenn ja, könnten Sie

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

verwenden, um eine Liste der Namen aller enthaltenen Ressourcen zu erhalten. Auf diese Weise können Sie den Ressourcennamen finden, der Ihrem Bild zugewiesen wurde.

+0

Warum nicht 'GetCallingAssembly' anstelle von' GetExecutingAssembly' verwenden? – Odys

25

Du bist wahrscheinlich auf der Suche nach Application.GetResourceStream

StreamResourceInfo sri = Application.GetResourceStream(new Uri("Images/foo.png")); 
if (sri != null) 
{ 
    using (Stream s = sri.Stream) 
    { 
     // Do something with the stream... 
    } 
} 
+4

Um hinzuzufügen, müssen Dateien als "Ressource" erstellt werden. http://StackOverflow.com/a/7394894/355264 –

Verwandte Themen