C#reflection和查找所有引用
鉴于一个DLL文件,我希望能够find该DLL文件中的方法的所有调用。 我该怎么做?
从本质上讲,我怎样才能以编程方式做Visual Studio已经做了什么?
我不想使用像.NET Reflector这样的工具来做到这一点,但reflection是好的,可能是必要的。
要找出使用方法MyClass.Foo()
位置,必须分析所有包含MyClass
的程序集引用的程序集的所有类。 我写了一个这个代码如何看起来像一个简单的概念certificate。 在我的例子中,我使用了Jb Evain编写的这个库 (它只是一个单独的.cs文件 )
我写了一个testing课来分析:
public class TestClass { public void Test() { Console.WriteLine("Test"); Console.Write(10); DateTime date = DateTime.Now; Console.WriteLine(date); } }
我写了这段代码打印出TestClass.Test()
使用的所有方法:
MethodBase methodBase = typeof(TestClass).GetMethod("Test"); var instructions = MethodBodyReader.GetInstructions(methodBase); foreach (Instruction instruction in instructions) { MethodInfo methodInfo = instruction.Operand as MethodInfo; if(methodInfo != null) { Type type = methodInfo.DeclaringType; ParameterInfo[] parameters = methodInfo.GetParameters(); Console.WriteLine("{0}.{1}({2});", type.FullName, methodInfo.Name, String.Join(", ", parameters.Select(p => p.ParameterType.FullName + " " + p.Name).ToArray()) ); } }
它给了我以下输出:
System.Console.WriteLine(System.String value); System.Console.Write(System.Int32 value); System.DateTime.get_Now(); System.Console.WriteLine(System.Object value);
这个例子显然很不完整,因为它不处理ref和out参数,也不处理generics参数。 我相信也忘记了其他的细节。 这只是表明它可以做到。
仅靠reflection不足以find给定assembly中的方法的所有引用。 reflection为任何特定方法( MethodInfo.GetMethodBody.GetILAsByteArray )的主体提供了一个字节数组,您必须自己parsing它以引用其他方法。 有几个公开的“ CIL阅读器”库(我没有使用它们 – 希望有人会发表更多)。
添加FxCop选项 – 根据您的场景,您可以重复使用由FxCop(Visual Studio代码分析)提供的CIL分析逻辑,并添加自定义规则(如果将其作为代码分析的一部分运行,则可以)。
您可以看看MSDN杂志文章确定.NET程序集和方法引用 。
我会考虑反映Visual Studio程序集,看看你是否能够在逆向工程的代码库中find它。 我相信VS实际上是在导航代码而不是reflection。 正如迈克尔所说的那样,反思对于确定一个组件的位数是非常重要的,但是对于这些位的使用者来说则不是。 但是,我没有重新审视反映,以证实我的怀疑。
请参阅堆栈溢出问题获取DLL的函数列表 。
从上面撕下(谢谢Jon Skeet):
对于特定的程序集,可以使用Assembly.GetTypes来获取types,然后为每个types调用Type.GetMethods(),Type.GetProperties()等,或者只是Type.GetMembers()。
但是,对于插件function来说,拥有插件必须实现的通用接口通常是一个好主意 – 这可以减less您需要使用的reflection量。 使用Type.IsAssignableFrom()来检查一个types是否与特定的接口兼容。
您可能还想看看可以使实现扩展系统更容易的托pipe扩展框架。