PDB-Dateien mit der Common Compiler Infrastructure auslesen

Wie kann man zu einer Klasse bzw. Methode die Quelldatei und die Zeilennummer auslesen?

Microsoft hat auf Codeplex dazu ein nettes Projekt veröffentlicht: die  Common Compiler Infrastructure: Metadata API.

Folgender Code ist nötig:

using Microsoft.Cci;
...

 var host = new PeReader.DefaultHost();

 var r = (IAssembly)host.LoadUnitFrom(@"D:\Development\DonkeyTools\src\DonkeyPlanner\bin\Debug\DonkeyPlanner.exe");

 PdbReader/*?*/ pdbReader = null;
 string pdbFile = Path.ChangeExtension(@"D:\Development\DonkeyTools\src\DonkeyPlanner\bin\Debug\DonkeyPlanner.exe", "pdb");
 if (File.Exists(pdbFile))
 {
   using (var pdbStream = File.OpenRead(pdbFile))
   {
     pdbReader = new PdbReader(pdbStream, host);

     foreach (var type in r.GetAllTypes().Where(t => t.Name.Value == "MainWindow"))
     {
      foreach (var location in type.Locations)
      {
        var source = pdbReader.GetPrimarySourceLocationsFor(location);
      }

     foreach (var method in type.Methods)
     {
       Console.WriteLine(method.Name.Value);

       foreach (var location in method.Locations)
       {
         foreach (var source in pdbReader.GetPrimarySourceLocationsFor(location))
         {
            Console.WriteLine("LINE " + source.StartLine + " - " + source.EndLine);
         } 
       }
     }
    }
   }
 }

Die CCI muss man sich vorher bei Codeplex als Source herunterladen und kompilieren. Das Projekt besteht aus diversen Teilassemblies. In diesem Beispiel habe ich die Assemblies PeReader, PdbReader, MetadataHelper und MetadataModel benötigt.

Ein konkreter Einsatzzweck:

DonkeySpec erhält gerade ein Tracing von Spezifikation zu Source Code. Mit Hilfe der CCI kann nun von der Spec-Funktion direkt in den Quellcode gesprungen werden: