如何将.NET Core C#项目编译为原始IL代码
问题排查:ildasm 报无有效CLR头的原因
ildasm 完全支持 .NET Core/.NET 5+ 程序集,你遇到的报错和框架版本无关,核心原因是你生成的EXE不是标准IL程序集:
- 如果你开启了单文件发布(
<PublishSingleFile>true</PublishSingleFile>),生成的EXE是原生启动器+打包的运行时/程序集的混合文件,没有标准CLR头 - 如果你开启了Native AOT/ReadyToRun编译,IL已经被提前编译为原生机器码,同样不存在可被反编译的CLR元数据
只要关闭以上两个发布选项,正常编译生成的框架依赖DLL就可以被ildasm正常解析。
实现输出IL而非EXE的两种方案
对应你需要的两种输出形式,可直接选用以下实现方式:
方案1:输出可读IL汇编格式
- 方式一:编译生成标准IL格式的DLL后,直接执行命令导出IL:
导出的ildasm YourProject.dll /output:Result.il.il文件就是和你给出的示例格式完全一致的可读IL汇编,包含所有方法、类型的元数据注释。 - 方式二:无需依赖ildasm,在项目内直接引用
System.Reflection.Metadata或Mono.Cecil库,在程序集编译完成的内存流阶段直接解析方法体的IL指令,按自定义格式逐行输出即可,不需要落地生成EXE/DLL文件。
方案2:输出原始二进制IL操作码
- 如果只需要单个方法的原始IL字节码:直接用
System.Reflection.Emit.ILGenerator动态构建方法体,构建完成后通过MethodBody.GetILAsByteArray()方法就能拿到原始IL字节数组,这个数组就是CLR JIT可以直接编译执行的二进制IL操作码,直接写入目标文件即可,不需要生成完整EXE。 - 如果需要完整程序集级别的IL二进制:用
AssemblyBuilder构建动态程序集,指定PE类型为PortableExecutableKinds.ILOnly,将生成的程序集直接写入内存流,流内的内容就是标准的可被CLR加载执行的IL二进制格式,不需要保存为EXE后缀文件。
注意:不要对输出的程序集做裁剪、单文件打包、AOT编译操作,否则会破坏原始IL结构,无法得到你要的纯IL内容。
内容的提问来源于stack exchange,提问作者boooba
相关产品推荐
相关产品推荐

