ICSharpCode.Dompiler+Mono.Cecil->;如何为单个方法生成代码
本文关键字:单个 方法 代码 Cecil- Dompiler+Mono gt ICSharpCode | 更新日期: 2023-09-27 18:28:47
我可以使用Mono.Cecil和ICSharpCode.Dompiler来生成类型或程序集的代码。
但是,如果我尝试为单个方法生成代码,我会得到一个错误"Object reference not set to a instance of a Object"
你们能给我一些提示吗?感谢大家的帮助。
为程序集中的所有类型生成代码的代码:
DirectoryInfo di = new DirectoryInfo(appPath);
FileInfo[] allAssemblies = di.GetFiles("*.dll");
foreach (var assemblyFile in allAssemblies)
{
string pathToAssembly = assemblyFile.FullName;
System.Reflection.Assembly assembly = System.Reflection.Assembly.ReflectionOnlyLoadFrom(pathToAssembly);
Mono.Cecil.AssemblyDefinition assemblyDefinition = Mono.Cecil.AssemblyDefinition.ReadAssembly(pathToAssembly,parameters);
AstBuilder astBuilder = null;
foreach (var typeInAssembly in assemblyDefinition.MainModule.Types)
{
if (typeInAssembly.IsPublic)
{
Console.WriteLine("T:{0}", typeInAssembly.Name);
//just reset the builder to include only code for a single type
astBuilder = new AstBuilder(new ICSharpCode.Decompiler.DecompilerContext(assemblyDefinition.MainModule));
astBuilder.AddType(typeInAssembly);
StringWriter output = new StringWriter();
astBuilder.GenerateCode(new PlainTextOutput(output));
string result = output.ToString();
output.Dispose();
}
}
}
为程序集中的所有公共方法生成代码的代码:
DirectoryInfo di = new DirectoryInfo(appPath);
FileInfo[] allAssemblies = di.GetFiles("*.dll");
foreach (var assemblyFile in allAssemblies)
{
string pathToAssembly = assemblyFile.FullName;
System.Reflection.Assembly assembly = System.Reflection.Assembly.ReflectionOnlyLoadFrom(pathToAssembly);
Mono.Cecil.AssemblyDefinition assemblyDefinition = Mono.Cecil.AssemblyDefinition.ReadAssembly(pathToAssembly,parameters);
AstBuilder astBuilder = null;
foreach (var typeInAssembly in assemblyDefinition.MainModule.Types)
{
if (typeInAssembly.IsPublic)
{
Console.WriteLine("T:{0}", typeInAssembly.Name);
foreach (var method in typeInAssembly.Methods)
{
//just reset the builder to include only code for a single method
astBuilder = new AstBuilder(new ICSharpCode.Decompiler.DecompilerContext(assemblyDefinition.MainModule));
astBuilder.AddMethod(method);
if (method.IsPublic && !method.IsGetter && !method.IsSetter && !method.IsConstructor)
{
Console.WriteLine("M:{0}", method.Name);
StringWriter output = new StringWriter();
astBuilder.GenerateCode(new PlainTextOutput(output));
string result = output.ToString();
output.Dispose();
}
}
}
}
}
我也遇到了同样的问题。您应该设置解压缩内容的CurrentType属性。将代码更改为
astBuilder = new AstBuilder(new ICSharpCode.Decompiler.DecompilerContext(assemblyDefinition.MainModule) { CurrentType = typeInAssembly } );
当我最近实现了一个快速的C#反编译器(基于MonoDecompiler)时,我使用了ILSpy方法:)
public string getSourceCode(MethodDefinition methodDefinition)
{
try
{
var csharpLanguage = new CSharpLanguage();
var textOutput = new PlainTextOutput();
var decompilationOptions = new DecompilationOptions();
decompilationOptions.FullDecompilation = true;
csharpLanguage.DecompileMethod(methodDefinition, textOutput, decompilationOptions);
return textOutput.ToString();
}
catch (Exception exception)
{
PublicDI.log.error("in getSourceCode: {0}", new object[] { exception.Message });
return ("Error in creating source code from IL: " + exception.Message);
}
}
有关此示例和其他示例,请参见:https://github.com/o2platform/O2.Platform.Scripts/blob/master/3rdParty/MonoCecil/CecilDecompiler/CecilDecompiler.cs
独立的迷你C#反编译工具是由这个脚本创建的https://github.com/o2platform/O2.Platform.Scripts/blob/master/3rdParty/MonoCecil/Utils/Tool%20-%20C%23%20Quick%20Decompiler.h2