2009-09-07 3 views
27

Mam obraz w aplikacji C# WPF, której akcja kompilacji jest ustawiona na "Zasób". Jest to po prostu plik w katalogu źródłowym, nie został dodany do kolekcji zasobów aplikacji za pośrednictwem okna dialogowego właściwości przeciągania/upuszczania. Próbuję napisać to jako strumień, ale nie mogę go otworzyć, mimo że próbuję kilka odmian kropek, ukośników, przestrzeni nazw i pozornie wszystkiego innego.Zasób ze złożenia jako strumień

Mogę uzyskać do niego dostęp w innym miejscu, zarówno w xaml z "pack: // application :,,, Resources/images/flags/tr.png", ale nie mogę uzyskać strumienia zawierającego go.

Większość miejsc zdają się mówić Użyj

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

Które nie miałem żadnych szczęścia.

Odpowiedz

23

GetManifestResourceStream jest dla tradycyjnych zasobów .NET to znaczy te, odniesione w plikach RESX. Nie są to te same zasoby, co zasoby WPF, np. Te, które zostały dodane za pomocą akcji kompilacji zasobów. Aby uzyskać do nich dostęp, powinieneś użyć Application.GetResourceStream, przekazując odpowiednią paczkę: URI. Zwraca obiekt StreamResourceInfo, który ma właściwość Stream, aby uzyskać dostęp do danych zasobu.

+0

Dzięki, nigdy bym tego nie znalazł. :) – Echilon

1

Nie trzeba wywoływać metody Close(), zostanie ona automatycznie wywołana przez Dispose() na końcu klauzuli using. Twój kod może wyglądać następująco:

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

Jak ta odpowiedź na pytanie? –

+0

Naprawdę? Przydatny wgląd, jeśli to prawda. Zawsze myślałem, że jawnie wywołanie Close było lepsze dla strumieni/plików. – Echilon

+0

Zastosowanie instrukcji Using bezpośrednio wywołuje metodę dispose w strumieniu, który niejawnie wywołuje metodę Close. Również instrukcja using używa zawsze "używanego" obiektu, nawet jeśli został zgłoszony wyjątek, więc użycie jest instrukcją all-inclusive, prawie bez błędu. – BeardinaSuit

6

Jeśli dobrze Ci poszło, masz problem z otworzeniem strumienia zasobów, ponieważ nie znasz jego dokładnej nazwy? Jeśli tak, możesz użyć tej opcji, aby uzyskać listę nazw wszystkich uwzględnionych zasobów. W ten sposób możesz znaleźć nazwę zasobu przypisaną do obrazu.

+0

Dlaczego nie użyć 'GetCallingAssembly' zamiast' GetExecutingAssembly'? – Odys

25

Pewnie szuka 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

Aby dodać, pliki muszą być budowane jako "Zasób". http://stackoverflow.com/a/7394894/355264 –