首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何只从.net程序集中读取元数据字节

如何只从.net程序集中读取元数据字节
EN

Stack Overflow用户
提问于 2018-02-17 14:21:44
回答 1查看 838关注 0票数 1

由于反射加载不再适用于.NET核心,所以我在System.Reflection.Metadata上实现了一个包装器,允许我扫描程序集中包含的类型,而不需要完整的程序集加载。

虽然MetadataReader基本上是工作的,但我实现它的步骤如下:

代码语言:javascript
复制
 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);
}

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

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

EN

回答 1

Stack Overflow用户

发布于 2018-02-17 19:11:38

感谢汉斯·帕桑特的评论,我想出了如下结论:

内存映射文件的形式加载程序集

代码语言:javascript
复制
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

代码语言:javascript
复制
using (var file = LoadAssembly(filename, out var length, out var access)) {
    using (var stream = file.CreateViewStream(0, length, access)) {

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

代码语言:javascript
复制
var headers = new PEHeaders(stream);

然后,我能够从流中获得指向文件开始的实际指针,并将其传递到MetadataReader构造函数中。

代码语言:javascript
复制
var start = (byte*)0;
stream.SafeMemoryMappedViewHandle.AcquirePointer(ref start);
var size = headers.MetadataSize;
var reader = new MetadataReader(start + headers.MetadataStartOffset, size, options, decoder);
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48842294

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档