我想知道是否可以在以下示例中将.NET控制台应用程序入口点从Main
更改为Main2
方法:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Main");
}
//desired entry point
static void Main2(string[] args)
{
Console.WriteLine("Main2");
}
}
我调查了这两个的IL代码。这是Main
方法:
.method private hidebysig static void
Main(
string[] args
) cil managed
{
.entrypoint
.maxstack 8
// other instructions
} // end of method Program::Main
还有Main2
方法:
.method private hidebysig static void
Main2(
string[] args
) cil managed
{
.maxstack 8
//other instructions
} // end of method Program::Main2
唯一的区别是.entrypoint
方法中Main
指令的正确性,据我所知,是在应用程序启动时由CLR检测到的。
是否有任何方法可以影响csc
以此指令标记其他方法?其他编译器可以做到这一点吗?
编辑
我的问题与this one不同,因为我要问的是csc
编译器(和其他编译器)的行为……尤其是如何将.entrypoint
指令放在其他地方
答案 0 :(得分:1)
该方法确实必须称为Main
,但是您可以使用-main
选项来指定哪个类的Main
方法是入口点。
(使用Main
作为入口是C#定义的一部分–在C#v5规范中,它在§3.1中,您也许可以克服,但您可以自己解决。 )
答案 1 :(得分:1)
这是不可能的,根据定义,Main
是C#应用程序的入口点。
Main方法是C#应用程序的入口点。 (库和服务不需要Main方法作为入口点。) 应用程序启动后,Main方法是第一个方法,即 调用。
来源:MSDN
答案 2 :(得分:1)
入口点必须命名为Main
,如C#语言规范§3.1所述:
3.1应用程序启动
应用程序启动 在执行环境调用指定方法时发生,该方法称为应用程序的条目 点。此入口点方法始终命名为
Main
,并且可以具有 以下签名之一:static void Main() {...} static void Main(string[] args) {...} static int Main() {...} static int Main(string[] args) {...}
看到单词“总是被命名为Main
”吗?如果您通过编写另一个编译器将入口点更改为Main
以外的其他名称,那么根据定义,该编译器将不是C#编译器。 :)
答案 3 :(得分:0)
这可以通过使用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");
这将产生以下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
如果执行Test.exe
,则会看到Main2
方法已执行