如何使用ILGenerator生成包含Main函数的可执行exe文件?
用ILGenerator生成带Main函数的EXE文件
当然可以用ILGenerator生成包含Main函数的EXE文件,核心是创建动态程序集时配置正确参数,并指定程序集的入口点。以下是具体实现步骤和示例:
关键配置要点
- 创建动态程序集时,选择支持保存的访问模式(
AssemblyBuilderAccess.RunAndSave或AssemblyBuilderAccess.Save) - 定义符合.NET入口要求的
Main方法(必须是public static,返回类型为void或int) - 调用
AssemblyBuilder.SetEntryPoint()指定程序集的入口方法 - 保存时指定
.exe后缀的输出文件名
完整代码示例
using System; using System.Reflection; using System.Reflection.Emit; class ILExeGenerator { static void Main() { // 定义程序集名称 var assemblyName = new AssemblyName("UnixTimestampTool"); // 创建可保存的动态程序集 var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave); // 定义EXE模块(文件名带.exe后缀) var moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName.Name, $"{assemblyName.Name}.exe"); // 定义包含业务方法和Main的类型 var typeBuilder = moduleBuilder.DefineType("TimestampUtils", TypeAttributes.Public | TypeAttributes.Class); // 定义EpochTime静态字段 var epochField = typeBuilder.DefineField("EpochTime", typeof(DateTime), FieldAttributes.Public | FieldAttributes.Static); epochField.SetValue(null, new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)); // 定义UnixTimestamp方法 var unixMethod = typeBuilder.DefineMethod( "UnixTimestamp", MethodAttributes.Public | MethodAttributes.Static, typeof(long), new[] { typeof(DateTime) } ); var unixIl = unixMethod.GetILGenerator(); // 实现逻辑:计算传入时间到Epoch的秒数并转为long unixIl.Emit(OpCodes.Ldarg_0); unixIl.Emit(OpCodes.Ldsfld, epochField); unixIl.Emit(OpCodes.Call, typeof(DateTime).GetMethod("op_Subtraction", new[] { typeof(DateTime), typeof(DateTime) })); unixIl.Emit(OpCodes.Callvirt, typeof(TimeSpan).GetProperty("TotalSeconds").GetGetMethod()); unixIl.Emit(OpCodes.Conv_I8); unixIl.Emit(OpCodes.Ret); // 定义Main入口方法 var mainMethod = typeBuilder.DefineMethod( "Main", MethodAttributes.Public | MethodAttributes.Static, typeof(void), Type.EmptyTypes ); var mainIl = mainMethod.GetILGenerator(); // 生成调用Console.WriteLine(UnixTimestamp(EpochTime))的IL指令 mainIl.Emit(OpCodes.Ldsfld, epochField); mainIl.Emit(OpCodes.Call, unixMethod); mainIl.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new[] { typeof(long) })); mainIl.Emit(OpCodes.Ret); // 完成类型定义 typeBuilder.CreateType(); // 设置程序集入口点为Main方法 assemblyBuilder.SetEntryPoint(mainMethod); // 保存生成的EXE文件 assemblyBuilder.Save($"{assemblyName.Name}.exe"); Console.WriteLine("EXE文件已成功生成"); } }
说明
- 运行上述代码后,会在输出目录生成
UnixTimestampTool.exe,执行后会输出Epoch时间对应的Unix时间戳(通常是0) - 如果需要生成Windows窗体应用,只需调整入口方法的类型和相关IL指令即可,核心配置逻辑一致
内容的提问来源于stack exchange,提问作者wang kai
相关产品推荐
相关产品推荐

