我一直在关注这篇文章来生成一个动态程序集,如下所示:
var directory = new DirectoryInfo(Environment.GetFolderPath(Environment.SpecialFolder.Desktop));
var file = new FileInfo(Path.Combine(directory.FullName, @"MyDynamicAssembly.exe"));
var domain = AppDomain.CurrentDomain;
var name = new AssemblyName("Namespace.With.Dots");
var builderAssembly = domain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Save, directory.FullName);
var builderModule = builderAssembly.DefineDynamicModule("Namespace.With.Dots.Temp.exe");
var builderType = builderModule.DefineType("Program", TypeAttributes.Class | TypeAttributes.Public, typeof(object));
var builderMethod = builderType.DefineMethod("Main", MethodAttributes.Private | MethodAttributes.Static, typeof(int), new Type [] { typeof(string []) });
var generator = builderMethod.GetILGenerator();
generator.Emit(OpCodes.Ldstr, "Hello, World!");
generator.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type [] { typeof(string) }));
generator.EmitWriteLine("Hello again.");
generator.Emit(OpCodes.Ldc_I4, 0);
generator.Emit(OpCodes.Ret);
builderAssembly.SetEntryPoint(builderMethod, PEFileKinds.ConsoleApplication);
builderAssembly.Save(file.Name, PortableExecutableKinds.ILOnly, ImageFileMachine.I386);
var process = Process.Start(file.FullName); // Crashes with image below.
var result = process.WaitForExit();
var exitCode = process.ExitCode; // -532462766.
以下是我对上面代码的了解:
- 它正在创建一个动态程序集,仅保存。
- 程序集名称、模块名称和输出 PE 名称都是不同的(我假设这不是问题)。
- 它创建了一个名为 Program 的公共静态类。
- 它在这个类中创建一个带有签名的方法
private static int Main (string [])
。 - 它将此方法设置为入口点并将程序集配置为控制台应用程序。
- 它将程序集编写为与处理器架构无关的 ILOnly。
- 它将程序集映像配置为我正在运行的 i386(带有 Intel 处理器的 Win7 32 位)。
方法:
- 将字符串文字引用推送到堆栈。
Console.WriteLine
使用从堆栈中获取的参数进行调用。Console.WriteLine
使用 再次调用EmitWriteLine
。- 将 0 作为 Int32 推入堆栈作为返回值。
- 返回。
碰撞:
忽略图像上的文件名。这将MyDynamicAssembly.exe
按照上面的代码。
任何关于这里出了什么问题的指针将不胜感激。