29

Let us say I have a C# class library project, which only contains xml files as embedded resources. I would like to access these resources from another solution project. As the 'class' library contains no classes it is quite hard to obtain the assembly like this:

typeof(ClassName).Assembly ...

to eventually get to the embedded resources. Is there a way to get to the embedded resources without having to hard code any magic strings etc.? Thanks.

PS:

This seems the only way possible at the moment:

var assembly = typeof(FakeClass).Assembly;
var stream = assembly.GetManifestResourceStream("Data.Blas.xml"); 

I have created a 'fake class' in my 'data' assembly.

Tipx
  • 7,367
  • 4
  • 37
  • 59
cs0815
  • 16,751
  • 45
  • 136
  • 299

2 Answers2

20

you can use Assembly.GetManifestResourceStream() to load the xml file from the embedded assembly.

System.IO.Stream s = this.GetType().Assembly.GetManifestResourceStream("ActivityListItemData.xml"); 

EDIT

You can use Assembly.Load() and load the target assembly and read the resource from there.

Assembly.LoadFrom("Embedded Assembly Path").GetManifestResourceStream("ActivityListItemData.xml");
Mike Cheel
  • 12,626
  • 10
  • 72
  • 101
Kurubaran
  • 8,696
  • 5
  • 43
  • 65
  • 3
    'this' would be the executing assembly but not the other one so this would not work! – cs0815 Jul 10 '13 at 12:05
  • you can use Assembly.Load() to load your assembly which has the embedded xml files and then read them, See the updated. – Kurubaran Jul 10 '13 at 12:11
  • 7
    Loading Resource from another project is not clearly explained (which is the main subject). What are we suposed to put in `Embedded Assembly Path`? A file path to the project? A relative one? From where? – Matthieu Charbonnier Apr 20 '22 at 10:05
2

Here is an approach I find works pretty well when I don't want loose files in the project. It can be applied to any assembly.

In the following example there is a folder in the root of the project called 'MyDocuments' and a file called 'Document.pdf' inside of that. The document is marked as an Embedded resource.

You can access the resource like this, building out the namespace first before calling GetManifestResourceStream():

Assembly assembly = Assembly.GetExecutingAssembly();
string ns = typeof(Program).Namespace;
string name = String.Format("{0}.MyDocuments.Document.pdf", ns);
using (var stream = assembly.GetManifestResourceStream(name))
{
    if (stream == null) return null;
    byte[] buffer = new byte[stream.Length];
    stream.Read(buffer, 0, buffer.Length);
    return buffer;
}

The only issue I have found is when the name space contains numbers after a '.' (e.g. MyDocuments.462). When a namespace is a number the compiler will prepend an underscore (so MyDocuments.462 becomes MyDocuments._462).

Mike Cheel
  • 12,626
  • 10
  • 72
  • 101
  • I would change the `typeof(Program).Namespace` as the Namespace doesn't always correlate with the name of the project and in those cases it won't find the file. Could change it to `string name = assembly.GetManifestResourceNames().FirstOrDefault(n => n.Contains(".MyDocuments.Document.pdf"));` – Arne H. Bitubekk Jan 03 '23 at 09:48