public static void GetLocalVariables(Assembly asm, MethodInfo m) { // Assembly asm = Assembly.GetExecutingAssembly(); ISymbolReader symreader = SymUtil.GetSymbolReaderForFile(asm.Location, null); if (symreader == null) { Console.WriteLine(" ERROR: no symreader was created. Aborting GetLocalVariables..."); return; } ISymbolMethod symMethod = symreader.GetMethod(new SymbolToken(m.MetadataToken)); int sequencePointCount = symMethod.SequencePointCount; ISymbolDocument[] docs = new ISymbolDocument[sequencePointCount]; int[] offsets = new int[sequencePointCount]; int[] lines = new int[sequencePointCount]; int[] columns = new int[sequencePointCount]; int[] endlines = new int[sequencePointCount]; int[] endcolumns = new int[sequencePointCount]; symMethod.GetSequencePoints(offsets, docs, lines, columns, endlines, endcolumns); Console.WriteLine(); Console.WriteLine("The source code for method: " + m.Name + "; found in " + docs[0].URL); Console.WriteLine(new String('*', 60)); // although there's an array of docs, they seem to all have the same value (?) so we'll only use the first one StreamReader reader = new StreamReader(docs[0].URL); // URL is typically a fully path-qualified filename string[] linesOfCode = reader.ReadToEnd().Split('\r'); string PrintableLineNumber = "0000"; Console.WriteLine(linesOfCode[lines[0] - 2].Replace('\n', ' ')); // the preceding line (assumes declaration is only one line long, and found on immediately precediting line! // foreach (int LineNumber in lines) // print the source code (comments omitted) for (int LineNumber = lines[0]; LineNumber < lines[sequencePointCount - 1] + 1; LineNumber++) // print the source code (including comments) { PrintableLineNumber = new String(' ', 4 - LineNumber.ToString().Length) // padding + LineNumber.ToString(); Console.WriteLine(PrintableLineNumber + ": " + linesOfCode[LineNumber - 1].Replace('\n', ' ')); } // Console.WriteLine(linesOfCode[lines[sequencePointCount -1] + 1].Replace('\n', ' ')); // the trailing line //Console.WriteLine(linesOfCode); reader.Close(); Console.WriteLine(new String('*', 60)); Console.WriteLine(); linesOfCode = null; }
public LocalVariableNameReader(MethodInfo m) { try { ISymbolReader symReader = SymUtil.GetSymbolReaderForFile(m.DeclaringType.Assembly.Location, null); ISymbolMethod met = symReader.GetMethod(new SymbolToken(m.MetadataToken)); VisitLocals(met.RootScope); } catch { Console.WriteLine(" ERROR: Failed LocalVariableNameReader() - perhaps this app needs to be compiled in x86?"); return; } }
// Wrapper. public static ISymbolReader GetSymbolReaderForFile(string pathModule, string searchPath) { return(SymUtil.GetSymbolReaderForFile( new System.Diagnostics.SymbolStore.SymBinder(), pathModule, searchPath)); }