Load resource from Assembly without loading the Assembly

Viewed 279

I looking for an API to extract a resource from an assembly but don’t want to load the assembly itself, not even in a separate AppDomain.

Is there a way of reading Assembly ManifestResourceStreams that isn’t Assembly.GetManifestResourceStream, which requires loading the Assembly?

Example of what I’m looking for:

var r = new AssemblyResourceReader(“Test.dll”);
Stream s = r.GetResourceStream(“image.png”);
2 Answers

Found an answer: the System.Reflection.Metadata package has such utilities

using System.IO;
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;

public static class AssemblyMetadataReader
{      
   public static byte[] GetManifestResource(string asmPath, string resourceName)
   {
      using (var fs = File.OpenRead(asmPath))
      {
         PEReader per = new PEReader(fs);
         MetadataReader mr = per.GetMetadataReader();
         foreach (var resHandle in mr.ManifestResources)
         {
            var res = mr.GetManifestResource(resHandle);
            if (!mr.StringComparer.Equals(res.Name, resourceName))
               continue;
         
            PEMemoryBlock resourceDirectory = per.GetSectionData(per.PEHeaders.CorHeader.ResourcesDirectory.RelativeVirtualAddress);
            var reader = resourceDirectory.GetReader((int)res.Offset, resourceDirectory.Length - (int)res.Offset);
            uint size = reader.ReadUInt32();
            return reader.ReadBytes((int)size);
         }
      }
      return null;
   }      
}


 
Related