views:

545

answers:

4

I have an image in a C# WPF app whose build action is set to 'Resource'. It's just a file in the source directory, it hasn't been added to the app's resource collection through the drag/drop properties dialog. I'm trying to write it as a stream, but I can't open it despite trying quite a few variations of dots, slashes, namespaces and seemingly everything else.

I can access it to use elsewhere either in xaml with "pack://application:,,,/Resources/images/flags/tr.png", but I can't get at a stream containing it.

Most places seem to say use

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

Which I haven't had any luck with.

+1  A: 

There's no need to call the Close() method, it will be automatically called by Dispose() at the end of the using clause. So your code might look like this:

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);
    }
}
Darin Dimitrov
How does this answer the question?
Frank Bollack
Really? Useful insight if it's true. I always thought explicitly calling Close was better for streams/files.
Echilon
The use of the Using statement is explicitly calling the dispose method of the Stream which is implicitly calling the Close method of it. Also the using statement always dispose the "used" object, even if an exception is raised, so the using is an all-inclusive, almost no-fault statement.
Mercure Integration
+1  A: 

If I get you right, you have a problem to open the resource stream, because you do not know its exact name? If so, you could use

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

to get a list of names of all included resources. This way you can find the resource name that was assignd to your image.

Frank Bollack
A: 

You're probably looking for Application.GetResourceStream

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

GetManifestResourceStream is for traditional .NET resources i.e. those referenced in RESX files. These are not the same as WPF resources i.e. those added with a build action of Resource. To access these you should use Application.GetResourceStream, passing in the appropriate pack: URI. This returns a StreamResourceInfo object, which has a Stream property to access the resource's data.

Phil Devaney
Thanks, I'd never have found that. :)
Echilon