Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# reflection and finding all references

Given a DLL file, I'd like to be able to find all the calls to a method within that DLL file. How can I do this?

Essentially, how can I do programmatically what Visual Studio already does?

I don't want to use a tool like .NET Reflector to do this, but reflection is fine and probably necessary.

like image 359
user420667 Avatar asked Mar 30 '11 17:03

user420667


People also ask

What do you mean by C?

" " C is a computer programming language. That means that you can use C to create lists of instructions for a computer to follow. C is one of thousands of programming languages currently in use.

What is the full name of C?

In the real sense it has no meaning or full form. It was developed by Dennis Ritchie and Ken Thompson at AT&T bell Lab. First, they used to call it as B language then later they made some improvement into it and renamed it as C and its superscript as C++ which was invented by Dr.

What is C in coding language?

C is a powerful general-purpose programming language. It can be used to develop software like operating systems, databases, compilers, and so on. C programming is an excellent language to learn to program for beginners. Our C tutorials will guide you to learn C programming one step at a time.


4 Answers

To find out where a method MyClass.Foo() is used, you have to analyse all classes of all assemblies that have a reference to the assembly that contains MyClass. I wrote a simple proof of concept of how this code can look like. In my example I used this library (it's just a single .cs file) written by Jb Evain:

I wrote a little test class to analyse:

public class TestClass
{
    public void Test()
    {
        Console.WriteLine("Test");
        Console.Write(10);
        DateTime date = DateTime.Now;
        Console.WriteLine(date);
    }
}

And I wrote this code to print out all the methods used within 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())
        );
    }
}

It gave me the following output:

System.Console.WriteLine(System.String value);
System.Console.Write(System.Int32 value);
System.DateTime.get_Now();
System.Console.WriteLine(System.Object value);

This example is obviously far from complete, because it doesn't handle ref and out parameters, and it doesn't handle generic arguments. I am sure that forgot about other details as well. It just shows that it can be done.

like image 104
Elian Ebbing Avatar answered Oct 22 '22 16:10

Elian Ebbing


You may take a look at the MSDN Magazine article Determining .NET Assembly and Method References.

like image 30
Darin Dimitrov Avatar answered Oct 22 '22 14:10

Darin Dimitrov


Reflection alone is not enough to find all references to a method in a given assembly. Reflection gives you a byte array for the body of any particular method (MethodInfo.GetMethodBody.GetILAsByteArray) and you have to parse it yourself for references to other methods. There are several publicly available "CIL reader" libraries (I have not used them - hopefully someone will post more on it).

Adding FxCop option - depending on your scenario, you may be able to reuse CIL parsing logic provided by FxCop (Visual Studio code analysis) and add your custom rules if running it as part of code analysis is OK for you.

like image 3
Alexei Levenkov Avatar answered Oct 22 '22 14:10

Alexei Levenkov


I would consider reflecting the Visual Studio assemblies and see if you can find it in the reverse engineered code base. I believe VS is actually navigating code rather than reflecting. Reflection, as Michael has posted, is great for determining the bits of an assembly, but not the consumers of those bits. I have not re-examined reflection to confirm my suspicions, however.

like image 1
Gregory A Beamer Avatar answered Oct 22 '22 14:10

Gregory A Beamer