我在Dr Dobbs处找到了以下代码(略有改写):
namespace TestEXEApp
{
public class Program
{
static void Main(string[] args)
{
AssemblyName an = new AssemblyName();
an.Name = "TestEXEApp";
AppDomain ad = AppDomain.CurrentDomain;
AssemblyBuilder ab = ad.DefineDynamicAssembly(an,
AssemblyBuilderAccess.Save);
ModuleBuilder mb = ab.DefineDynamicModule(an.Name, "Hello.exe");
TypeBuilder tb = mb.DefineType("TestEXEApp.Program",
TypeAttributes.Public | TypeAttributes.Class);
MethodBuilder fb = tb.DefineMethod("Main",
MethodAttributes.Public |
MethodAttributes.Static,
typeof(int), new Type[] { typeof(string[]) });
ILGenerator ilg = fb.GetILGenerator();
ilg.Emit(OpCodes.Ldstr, "Hello, World!");
ilg.Emit(OpCodes.Call, typeof(TestClasses.Class1).GetMethod("Test",
new Type[] { typeof(string) }));
ilg.Emit(OpCodes.Ldc_I4_0);
ilg.Emit(OpCodes.Ret);
// Seal the lid on this type
Type t = tb.CreateType();
// Set the entrypoint (thereby declaring it an EXE)
ab.SetEntryPoint(fb, PEFileKinds.ConsoleApplication);
// Save it
ab.Save("Hello.exe");
Console.WriteLine("Press enter...");
Console.ReadLine();
}
}
}
另外,我在一个名为TestClasses的单独项目中有以下类:
namespace TestClasses { public class Class1 { public static void Test(String t) { Console.WriteLine("Test: " + t); } } }
现在,当我编译它时,我(显然)得到两个文件“TestEXEApp.exe”和“TestClasses.dll”。如果我运行它,我会得到一个新文件“Hello.exe”,如果我运行这个新文件,它会输出“Test:Hello,World!”。到现在为止还挺好。现在,问题是,这个新文件显然取决于TestClasses.dll。因此,如果我将其发送到另一个目录,或者由于某种原因移动它,它就不能再执行了。
Reflection.Emit是否有某种方式以某种方式将TestClasses.Class1代码包含到Hello.exe可执行文件中,因此它变得100%自包含(除了依赖于.NET框架,显然) ?或者,如果无法完成,我怎样才能让程序输出TestClasses.dll的副本,以便我总是将dll文件写在与Hello.exe相同的目录中?