在dll中获取使用过的类

时间:2014-06-11 10:45:12

标签: c# assemblies mono.cecil

我正在检查一个dll文件,我需要知道在这个dll文件中使用了哪些类别的其他dll文件。使用第一个循环,可以遍历所有类的dll-但是现在我想获得所有类的列表,这些类在这个类中以某种方式使用(这些类具有特定的命名约定“Some.Test.Class *“)。 解决方案是解析类的每个方法的每个指令,而不是在指令中搜索类的名称? 有人有更好的主意吗?

foreach (TypeDefinition type in this.currentAssembly.MainModule.Types) 
{
    foreach (MethodDefinition method in type.Methods)
    {
       if (method.HasBody)
       {
           for (int cnt = 0; cnt < method.Body.Instructions.Count - 1; cnt++)
           {
               Instruction instruction = method.Body.Instructions[cnt];
               /*
                   ????????
               */
           }
       }
    }
}

P.S。:我不能加载一些引用的dll文件

1 个答案:

答案 0 :(得分:0)

我正在使用Mono.Cecil:

private static List<MethodDefinition> GetAllInnerMethods(MethodDefinition method)
{
    var queueMethodDefinition = new Queue<MethodDefinition>();
    var hsMethodDefinition = new HashSet<MethodDefinition>();

    queueMethodDefinition.Enqueue(method);

    while (queueMethodDefinition.Count > 0)
    {
        MethodDefinition methodCurr = queueMethodDefinition.Dequeue();
        if (!hsMethodDefinition.Contains(methodCurr))
        {
            hsMethodDefinition.Add(methodCurr);

            IEnumerable<MethodDefinition> innerMethodsByCaller = GetInnerMethodsByCaller(methodCurr);

            foreach (var currInnerMethod in innerMethodsByCaller)
            {
                if (!hsMethodDefinition.Contains(currInnerMethod))
                {
                    queueMethodDefinition.Enqueue(currInnerMethod);
                }
            }
        }
    }

    return hsMethodDefinition.ToList();
}

private static IEnumerable<MethodDefinition> GetInnerMethodsByCaller(MethodDefinition caller)
{
    return caller.Body.Instructions
        .Where(x => (x.OpCode == OpCodes.Call || x.OpCode == OpCodes.Calli || x.OpCode == OpCodes.Callvirt) && x.Operand is MethodDefinition)
        .Select(x => (MethodDefinition)x.Operand);
}