首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >删除方法后从PEVerify获取“类型加载失败”

删除方法后从PEVerify获取“类型加载失败”
EN

Stack Overflow用户
提问于 2017-01-13 18:11:51
回答 1查看 154关注 0票数 0

短篇小说

我正在使用下面的Mono.Cecil代码从接口和实现该接口的类中删除除两种方法之外的所有方法。

代码语言:javascript
复制
static void Main(string[] args)
{
    var moduleDef = ModuleDefinition.ReadModule("SomeService.dll");

    var bigService = moduleDef.Types.Single(t => t.Name == "BigService"); // interface
    var bigServiceClient = moduleDef.Types.Single(t => t.Name == "BigServiceClient"); // class implementing above interface
    var toSave = new[] {"method1", "method2"};

    SaveMethods(bigService, toSave);
    SaveMethods(bigServiceClient, toSave);

    moduleDef.Write(@"C:\AutobooksCode\MAIN\API\JHA\JHA.SymXchange.V2\bin\Release\JHA.SymXchange.V2_updated.dll");
}

private static void SaveMethods(TypeDefinition typeDef, string[] names)
{
    var methodsToSave = typeDef.Methods.Where(m => names.Contains(m.Name, StringComparer.OrdinalIgnoreCase)).ToList();
    var ctors = typeDef.Methods.Where(m => m.Name == ".ctor");

    methodsToSave.AddRange(ctors);

    // remove all methods except the ones I want to save
    var pos = 0;
    while (true)
    {
        if (typeDef.Methods.Count == methodsToSave.Count)
            break;

        if (methodsToSave.Contains(typeDef.Methods[pos]))
            pos++;
        else
        {
            typeDef.Methods.RemoveAt(pos);
        }
    }
}

代码工作正常,ILDASM和JustDecompile看起来都很好,最好的是,DLL可以很好地处理客户端。但是,运行彻底的PEVerify会为[token 0x02001C35]生成一个Type load failed.错误。

我使用ILDASM /TOK查看哪个令牌是0x02001C35,它是我正在修改的类(BigServiceClient)。我只是不明白这是怎么回事。

有关于如何进一步调查PEVerify错误的指示/想法/提示吗?

长篇小说

我正在处理遗留的SOAP接口。我使用svcutil来生成代理,但是由于这个接口的遗留特性,这些代理是单个类中的巨型 --类似于1500+方法。这在对象创建中造成了一些性能问题,也导致了一些使用Castle的代理问题。

作为一个快速测试,我从生成的1500+代理文件中删除了除了两个方法(是的,只有两个.cs代理文件中的两个)之外的所有方法,重新编译后得到了更好的结果。时间从6-7秒一直持续到20毫秒以下。

编辑这些文件来手动删除这些文件是很繁琐的,所以我想我应该用Mono.Cecil实现它的自动化。如前所述,一切都正常运行,但我关心的是peverify错误。

我知道你可以做一些非常复杂和疯狂的事情与IL编织,但我只需要删除一堆未使用的方法。是的,我可以手动解析生成的源代码并在那里删除它,但是如果您见过从svcutil生成的SOAP代理,那么这是我想要避免的路径。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-01-13 22:53:18

发现了问题。具有讽刺意味的是,我在编写代码手动处理源文件并将其剪短时发现了这个问题。:)

在编写源文件处理器时,我注意到svcutil生成了两个implicit interface implementation as well as an explicit interface implementation。我以前的SaveMethods代码太激进了,并且删除了显式的实现。我怀疑这是导致来自Type load failed的PEVerify错误的原因。

下面是我更新的SaveMethods实现,它生成一个成功完成PEVerify的程序集:

代码语言:javascript
复制
private static void SaveMethods(TypeDefinition typeDef, IEnumerable<string> names)
{
    var pos = 0;
    while (true)
    {
        if (pos == typeDef.Methods.Count)
            break;

        var md = typeDef.Methods[pos];

        // save ctors, method implementations and explicit interface implementations
        if (md.Name == ".ctor" ||
            names.Contains(md.Name) ||
            (md.Overrides.Count > 0 && names.Contains(md.Overrides[0].Name)))
        {
            pos++;
        }
        else
        {
            typeDef.Methods.RemoveAt(pos);
        }
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41640941

复制
相关文章

相似问题

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