如何更改 ac# 控制台应用程序的入口点?

Art*_*tem 5 .net c# clr cil csc

我想知道是否可以将 .NET 控制台应用程序入口点从以下示例中的方法更改Main为:Main2

class Program
{ 
    static void Main(string[] args)
    {
        Console.WriteLine("Main");
    }

    //desired entry point
    static void Main2(string[] args)
    {
        Console.WriteLine("Main2");
    }
}
Run Code Online (Sandbox Code Playgroud)

我调查了这两个的 IL 代码。这是Main方法:

  .method private hidebysig static void 
    Main(
      string[] args
    ) cil managed 
  {
    .entrypoint
    .maxstack 8

    // other instructions

  } // end of method Program::Main
Run Code Online (Sandbox Code Playgroud)

以及Main2方法:

.method private hidebysig static void 
    Main2(
      string[] args
    ) cil managed 
  {
    .maxstack 8

    //other instructions
  } // end of method Program::Main2
Run Code Online (Sandbox Code Playgroud)

唯一的区别是.entrypoint instruction in the Main method, which is - as far as I understand - detected by CLR when application is started.

有什么办法可以影响csc to mark other method with this instruction? Can other compilers do the trick?

编辑 我的问题与这个不同,因为我问的是csc 编译器(和其他编译器)的行为......特别是如何将.entrypoint指令放在其他地方

Art*_*tem 4

AssemblyBuilder这可以通过使用库中的其他内容来实现System.Reflection

AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("Test"),AssemblyBuilderAccess.Save);
TypeBuilder typeBuilder = assemblyBuilder.DefineDynamicModule("Module","Test.exe",false).DefineType("Program",TypeAttributes.Public);
MethodBuilder methodBuilder = typeBuilder.DefineMethod("Main2",MethodAttributes.Public|MethodAttributes.Static);
ILGenerator ilGenerator = methodBuilder.GetILGenerator();
ilGenerator.EmitWriteLine("Main2");
ilGenerator.Emit(OpCodes.Ret);
assemblyBuilder.SetEntryPoint(methodBuilder);
typeBuilder.CreateType();
assemblyBuilder.Save("Test.exe");
Run Code Online (Sandbox Code Playgroud)

这会产生以下IL代码(.entryPoint放置在Main2方法上):

.method public static 
void Main2 () cil managed 
{
    // Method begins at RVA 0x2050
    // Code size 11 (0xb)
    .maxstack 1
    .entrypoint

    IL_0000: ldstr "Main2"
    IL_0005: call void [mscorlib]System.Console::WriteLine(string)
    IL_000a: ret
} // end of method Program::Main2
Run Code Online (Sandbox Code Playgroud)

如果你执行Test.exe你会看到该Main2方法被执行