【问题标题】:How to read ONLY the metadata bytes from a .net assembly如何仅从 .net 程序集中读取元数据字节
【发布时间】:2018-02-17 14:21:44
【问题描述】:

由于仅反射加载不再适用于 .NET Core,因此我正在实现 System.Reflection.Metadata 的包装器,以允许我扫描程序集以查找其中包含的类型,而无需完全加载程序集。

虽然 MetadataReader 基本上可以正常工作,但我的实现方式如下:

 private unsafe MetadataReader LoadMetadataReader(
    string filename,
    MetadataReaderOptions options = MetadataReaderOptions.Default,
    MetadataStringDecoder decoder = null)
{
    buffer = File.ReadAllBytes(filename);
    pinnedHandle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
    var headers = new PEHeaders(new MemoryStream(buffer));
    var startOffset = headers.MetadataStartOffset;
    var metaDataStart = (byte*)pinnedHandle.AddrOfPinnedObject() + startOffset;
    return new MetadataReader(metaDataStart, headers.MetadataSize, options, decoder);
}

这意味着我每次都在加载程序集的所有字节。

我的问题是:有没有办法只识别和加载文件中读取元数据所需的字节子集?

【问题讨论】:

  • 我没有答案,但解决方法(假设问题是内存使用)可能是创建一个 AppDomain,加载类型,然后在完成后卸载它读取数据。
  • 也许您可以将 FileStream 而不是 MemoryStream 提供给 PEHeaders 构造函数。然后它将(我假设)从该流中只读标题,并且标题将为您提供有关元数据记录大小的信息,然后您可以加载这些信息。
  • 我会尽量在这里使用 MemoryMappedFile。就像 CLR 一样。 .NETCore 有点模糊,但有一个 Nuget 包。

标签: c# reflection metadata


【解决方案1】:

感谢 Hans Passant 的评论,我解决了:

将程序集加载为Memory Mapped File

private static MemoryMappedFile LoadAssembly(string filename, out long length, out MemoryMappedFileAccess access)
{
    // Setup parameters to pass in
    return MemoryMappedFile.CreateFromFile(filename, mode, mapName, length, access);
}

创建MemoryMappedViewStream

using (var file = LoadAssembly(filename, out var length, out var access)) {
    using (var stream = file.CreateViewStream(0, length, access)) {

通过PEHeaders 对象从流中获取标头的尺寸

var headers = new PEHeaders(stream);

然后我能够从流中获取指向文件开头的实际指针并将其传递给MetadataReader 构造函数

var start = (byte*)0;
stream.SafeMemoryMappedViewHandle.AcquirePointer(ref start);
var size = headers.MetadataSize;
var reader = new MetadataReader(start + headers.MetadataStartOffset, size, options, decoder);

【讨论】:

    猜你喜欢
    • 2014-12-22
    • 1970-01-01
    • 1970-01-01
    • 2012-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-10
    相关资源
    最近更新 更多