finding file in root of wpf application

992 views Asked by At

I'm trying to load a file with pack://application: The file is situated in the root of my project but I keep getting a null reference error. However When I do an absolute reference it finds the file and loads just fine. What am I missing here?

This doesn't work

var txt = Application.GetContentStream(new Uri(@"pack://application:,,,/Layout.xml"));
string full = new StreamReader(txt.Stream).ReadToEnd();

or any variation with Pack://Application,,,/

This works, but I don't want to use it and seems bad practice anyway

var path = AppDomain.CurrentDomain.BaseDirectory.Substring(0, (AppDomain.CurrentDomain.BaseDirectory.Length - 10));
var txt = path + @"Layout.xml";
string full = new StreamReader(txt).ReadToEnd();
2

There are 2 answers

1
Contango On BEST ANSWER

First, ensure that the file is definitely copied into your output ./bin/ directory on compile:

enter image description here

This worked perfectly for me in my WPF application:

const string imagePath = @"pack://application:,,,/Test.txt";
StreamResourceInfo imageInfo = Application.GetResourceStream(new Uri(imagePath));
byte[] imageBytes = ReadFully(imageInfo.Stream);

If you want to read it as binary (e.g. read an image file), you'll need this helper function. You probably won't need this, as you're reading an .xml file.

public static byte[] ReadFully(Stream input)
{
    byte[] buffer = new byte[16 * 1024];
    using (MemoryStream ms = new MemoryStream())
    {
        int read;
        while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
        {
            ms.Write(buffer, 0, read);
        }
        return ms.ToArray();
    }
}

For more, see Microsoft on Pack URIs in WPF.

0
nozzleman On

I'm not familiar with the way you are trying to achieve this. I use to solve this kind of problem differently:

First, embed the file you are trying to access in you application. This is done by setting the Build-Step-Property of the File (Properties-Window, when file is selected in VS) to Embedded Resource.

In your application, you can recieve a stream to that resource like that:

var stream = this.GetType().Assembly.GetManifestResourceStream("Namespace.yourfile.txt");

If you are unsure of the string you have to pass to GetManifestResourceStream(..), you can inspect what embedded resources are available and look for the one that is accociated with your file like so:

var embeddedResources = this.GetType().Assembly.GetManifestResourceNames()