/// <summary> /// Decompiles the method into C# code that cane be patched and replaced /// </summary> /// <param name="method"></param> /// <returns></returns> public static string Decompile(this MethodDefinition method) { var decompiler = new ICSharpCode.Decompiler.CSharp.CSharpDecompiler(method.Module, new ICSharpCode.Decompiler.DecompilerSettings() { }); return(decompiler.DecompileAsString(new[] { method })); }
public string Dump(string methodName = null) { using (var testEnvironment = RuntimeEnvironmentFactory.Create(_dependencies)) { string mainModuleFullName = Emit(testEnvironment, manifestResources: null, EmitOptions.Default); IList <ModuleData> moduleDatas = testEnvironment.GetAllModuleData(); var mainModule = moduleDatas.Single(md => md.FullName == mainModuleFullName); RuntimeEnvironmentUtilities.DumpAssemblyData(moduleDatas, out var dumpDir); string extension = mainModule.Kind == OutputKind.ConsoleApplication ? ".exe" : ".dll"; string modulePath = Path.Combine(dumpDir, mainModule.SimpleName + extension); var decompiler = new ICSharpCode.Decompiler.CSharp.CSharpDecompiler(modulePath, new ICSharpCode.Decompiler.DecompilerSettings() { AsyncAwait = false }); if (methodName != null) { var map = new Dictionary <string, ICSharpCode.Decompiler.TypeSystem.IMethod>(); listMethods(decompiler.TypeSystem.MainModule.RootNamespace, map); if (map.TryGetValue(methodName, out var method)) { return(decompiler.DecompileAsString(method.MetadataToken)); } else { throw new Exception($"Didn't find method '{methodName}'. Available/distinguishable methods are: \r\n{string.Join("\r\n", map.Keys)}"); } } return(decompiler.DecompileWholeModuleAsString()); } void listMethods(ICSharpCode.Decompiler.TypeSystem.INamespace @namespace, Dictionary <string, ICSharpCode.Decompiler.TypeSystem.IMethod> result) { foreach (var nestedNS in @namespace.ChildNamespaces) { if (nestedNS.FullName != "System" && nestedNS.FullName != "Microsoft") { listMethods(nestedNS, result); } } foreach (var type in @namespace.Types) { listMethodsInType(type, result); } } void listMethodsInType(ICSharpCode.Decompiler.TypeSystem.ITypeDefinition type, Dictionary <string, ICSharpCode.Decompiler.TypeSystem.IMethod> result) { foreach (var nestedType in type.NestedTypes) { listMethodsInType(nestedType, result); } foreach (var method in type.Methods) { if (result.ContainsKey(method.FullName)) { // There is a bug with FullName on methods in generic types result.Remove(method.FullName); } else { result.Add(method.FullName, method); } } } }