0

I have bunch of dll written with C# and I know the namespace name used in it. i just need to get list of dll which uses sqlconnection.open() method or used namespace system.data.sqlclient in it.Is there some way to do it programmatically with C#?

GowthamanSS
  • 1,434
  • 4
  • 33
  • 58

1 Answers1

1

Try this:

class Program
{
    static void Main(string[] args)
    {
        var methodsCallingDbConnectionOpen = AssemblyDefinition.ReadAssembly(typeof(Program).Assembly.Location)
            .MainModule
            .GetTypes()
            .SelectMany(type => type.Methods)
            .Where(method => method.HasBody &&
                method.Body.Instructions.Any(instruction =>
                    instruction.OpCode.Code == Code.Callvirt && instruction.Operand is MethodReference &&
                    ((MethodReference)instruction.Operand).FullName.Contains("System.Data.Common.DbConnection::Open")));

        foreach (var method in methodsCallingDbConnectionOpen)
        {
            Console.WriteLine(method);
        }

        Console.ReadLine();
    }

    static void Foo()
    {
        using (var connection = new SqlConnection())
        {
            connection.Open();
        }
    }
}

Produces:

System.Void ConsoleApplication1.Program::Foo()

Notes:

  • This sample uses Mono.Cecil.
  • This sample detects call to DbConnection.Open. To detect which descendant of DbConnection being used, you have to look into previous IL instructions (e.g., ctor call).
Dennis
  • 37,026
  • 10
  • 82
  • 150
  • i am getting a error as 'Mono.Cecil.AssemblyDefinition' does not contain a definition for 'ReadAssembly' – GowthamanSS Aug 09 '12 at 14:49
  • can u say me which version of mono did u use it – GowthamanSS Aug 09 '12 at 15:14
  • @GowthamanSS, I've added reference to Cecil through NuGet, without downloading Mono: https://nuget.org/packages/Mono.Cecil/0.9.5.3. If you're using VS prior to 2010, you can download Cecil from its Github page: https://github.com/jbevain/cecil/ – Dennis Aug 09 '12 at 17:24
  • i have just replaced "System.Data.Common.DbConnection::Open" to "System.IO.File::Create" in order to find out method that uses create method but it throw me an error can u guide me – GowthamanSS Aug 10 '12 at 10:58
  • i do not get any exception it does not read the method name which having file.create() method inside it – GowthamanSS Aug 10 '12 at 11:49
  • what i did is i have change the "System.Data.Common.DbConnection::Open" to "System.IO.File::Create" and the below class as static void Foo() { File.Create("s.txt"); } i do not know whether is correct – GowthamanSS Aug 10 '12 at 11:55
  • @GowthamanSS: this is because of `OpCode.Code` - `File.Create` is a static method, so it is called via `call` (Code.Call). I would recommend you to read something more about call/callvirt IL instructions. – Dennis Aug 10 '12 at 12:02
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/15170/discussion-between-gowthamanss-and-dennis) – GowthamanSS Aug 10 '12 at 12:04